0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gitで指定行を別ファイルへ移動して履歴管理する

0
Posted at

Gitで指定した行だけを別ファイルへ移動し、Git管理する方法

背景

Gitで管理しているファイルを整理していると、一部の行だけを別ファイルへ切り出したくなることがある。

単純にコピーするだけなら難しくないが、今回は次の条件を満たしたかった。

  • 指定した行だけを別ファイルへ保存する
  • 元ファイルからはその行を削除する
  • 切り出したファイルもGitで履歴管理する

調べてみると、head・tail・sed を組み合わせることでシンプルに実現できた。

問題

最初はファイルの先頭40行を別ファイルへ保存したかった。
途中で要件が変わり、最終的には「4〜2898行目を別ファイルへ移動する」ことになった。
また、git diff | head -40 のようなコマンドと混同しやすい点にも注意が必要だった。

  • head -40 source_file はファイル本体の先頭40行を取得する
  • git diff | head -40 は差分表示の先頭40行を取得する

似ているようで用途はまったく異なる。

先頭40行を別ファイルへ保存する

先頭40行だけを保存する場合は head を使う。

head -40 source_file > extracted_lines

この時点では元ファイルは変更されない。

元ファイルから先頭40行を削除する

保存したあと、元ファイルから削除する場合は tail を利用する。

src="source_file"
dst="extracted_lines"

head -40 "$src" > "$dst"

tail -n +41 "$src" > "$src.tmp" &&
mv "$src.tmp" "$src"

tail -n +41 は41行目以降を出力する。

一時ファイルを経由しているため、途中で失敗した場合でも元ファイルが壊れにくい。

指定した行を別ファイルへ移動する

今回最終的に必要だったのは、4〜2898行目を別ファイルへ移動することだった。

sed を使うとシンプルに書ける。

src="source_file"
dst="extracted_lines"

# 4〜2898行目を保存
sed -n '4,2898p' "$src" > "$dst"

# 元ファイルから4〜2898行目を削除
sed '4,2898d' "$src" > "$src.tmp" &&
mv "$src.tmp" "$src"

使用しているコマンドは次のとおり。

コマンド 内容
sed -n '4,2898p' 4〜2898行目だけを出力
sed '4,2898d' 4〜2898行目を削除した結果を出力

直接元ファイルを書き換えるのではなく、一時ファイルへ出力してから置き換えている。

Gitで履歴管理する

切り出したファイルもGitで管理する場合は、元ファイルと新しいファイルを両方追加する。

まずは差分を確認する。

git diff -- "$src" "$dst"
git status --short

問題なければコミットする。

git add "$src" "$dst"

git commit -m "Move lines 4-2898 into a separate file"

これで次の変更履歴をGitで追跡できる。

  • 元ファイルから指定行が削除された履歴
  • 新しいファイルが追加された履歴

PowerShellで行う場合

Windows環境ではPowerShellでも同様のことができる。

$src = "source_file"
$dst = "extracted_lines"

$lines = Get-Content $src

# 4〜2898行目を保存
$lines[3..2897] | Set-Content $dst

# 元ファイルから4〜2898行目を削除
$lines[0..2] + $lines[2898..($lines.Count - 1)] |
    Set-Content $src

PowerShellでは配列の添字が0から始まるため、

  • 4行目 → インデックス3
  • 2898行目 → インデックス2897

となる点に注意したい。

また、ファイルが2898行未満の場合はエラーになるため、必要に応じて事前に行数を確認すると安全である。

(Get-Content $src).Count

学んだこと

今回の調査で整理できた点は次のとおり。

  • head はファイルの先頭行を取得する。
  • tail -n +N は指定行以降を取得できる。
  • sed -n '開始,終了p' で指定範囲だけを抽出できる。
  • sed '開始,終了d' で指定範囲を削除できる。
  • 元ファイルは一時ファイル経由で更新したほうが安全。
  • 切り出したファイルも git add すれば通常どおり履歴管理できる。
  • git diff | head -40 は差分表示の先頭40行であり、ファイルの先頭40行ではない。

まとめ

Git管理中のファイルから一部の行を別ファイルへ分離する場合は、head・tail・sed を組み合わせるだけで実現できる。

特に指定範囲の抽出と削除は sed を使うと簡潔で分かりやすい。

最後に元ファイルと新しいファイルを両方 git add すれば、変更履歴もGitで継続して管理できる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?