シェルスクリプトでファイルの最後からN行目に行を追加する

Bash

はじめに

シェルスクリプトで
「ファイルの先頭行からN行目に行を追加する」
のは簡単ですが、
「ファイルの最終行からN行目に行を追加する」
方法についてうまいやり方がないかについて質問されたのでワンライナーで実現できる方法について紹介します。

検証環境

$ bash -version
GNU bash, バージョン 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

ファイルの先頭行からN行目に行を追加する

sed を利用します。 i という内部コマンドを利用します。

# 検証用のテストファイルを作成
$ seq 1 10 > seq.txt

# 確認
$ cat seq.txt
1
2
3
4
5
6
7
8
9
10

# 先頭行から5行目に行を追加
$ cat seq.txt| sed '5i test' > seq2.txt

# 確認
$ cat seq2.txt
1
2
3
4
test
5
6
7
8
9
10

ファイルの最終行からN行目に行を追加する

sed に加えて tac コマンドを利用します。
仕組みは単純で、一度ファイルを逆順にしてから、先頭行からN行目に差し込んだ後、再度逆順にします。

ちなみに tac については以下のエントリでも取り上げています。

# 検証用のテストファイルを作成
$ seq 1 10 > seq.txt

# 確認
$ cat seq.txt
1
2
3
4
5
6
7
8
9
10

# 最終行から5行目に行を追加
$ tac seq.txt | sed '5i test' | tac > seq2.txt

# 確認
$ cat seq2.txt
1
2
3
4
5
6
test
7
8
9
10

ファイルサイズが大きい場合

ファイルサイズが大きいと処理時間がかかるので、その場合はもう少しマシなロジックを組むほうがいいですね。

$ LINENUM=$(cat seq.txt| wc -l)
$ cat seq.txt | sed "$((LINENUM-5+1))a test"

ひとこと

以下のエントリで忘れかけていたことが思い出せてよかった。

Bash