2015年2月26日木曜日

sedコマンドを使って指定した行の次の行に任意の文字列を追加する

概要

タイトルの通り
ある行の後ろにピンポイントで追記したいときってあると思います
いちいちvimやemacsを開くのも面倒なのでsedコマンドで追記してみました

環境

  • CentOS 6.6 64bit (Final)
  • sed 4.2.1

使い方

実際のコマンドと挙動は以下の通りです

テスト用ファイル

cat text.txt

hoge
hoge1
hoge2
hoge3
hoge4

3行目の後ろに追記する

sed '3a hoge-add' text.txt

hoge
hoge1
hoge2
hoge-add
hoge3
hoge4

or

sed '3N;s/\n/\nhoge-add\n/;' text.txt

hoge
hoge1
hoge2
hoge-add
hoge3
hoge4

指定した正規表現に該当する次の行に追記する

sed '/hoge2/a hoge-add' text.txt

hoge
hoge1
hoge2
hoge-add
hoge3
hoge4

or

sed '/hoge2/N;s/\n/\nhoge-add\n/;' text.txt

hoge
hoge1
hoge2
hoge-add
hoge3
hoge4

ちょっと解説

どちらも2パターン紹介してしますが「a」コマンドを使うほうがどちらも断然簡単です

「a」コマンドは

text を追加する。 text に改行を含めたい場合は、その前にバックスラッシュを置く。

「N」コマンドは

入力の次の行をパターンスペースに読み込む/追加する。

がそれぞれのコマンドの説明です
aコマンドは直感的でかつ単純です
Nコマンドが少々挙動が複雑でかつ指定方法も難読です

aコマンドは特に説明することはないと思います

Nコマンドを使って行を指定して追記する場合は「3N;」のように指定します
「3」の部分はそのまま行数に該当するので4とすれば4行目の次の行に追記することができます
置換する文字列は「\n」で改行を指定しています
今回はLinux上で挙動を確認したので「\n」LFの改行コードを指定いますがWindows環境のファイルなどで改行コードが「\r」の場合はそちらを指定してください
置換後の文字列の前後にも改行コードを入れることで行の追加を実現しています

また正規表現の方は「/hoge2/N;」といった感じで指定します
こっちの挙動が若干思った通りの挙動にはなりません
思った通りの挙動にならないのはNコマンドの説明を理解するとよくわかるのですが、Nコマンドは次の行を対象に置換を実行します
サンプルでは「hoge2」に該当する行が1行しかないので問題ないのですが例えば以下のように実行すると結果が飛び飛びになっていることがわかると思います

sed '/hoge/N;s/\n/\nhoge-add\n/;' text.txt

hoge
hoge-add
hoge1
hoge2
hoge-add
hoge3
hoge4
hoge-add

Nコマンドは1行目のhogeが見つかったら2行目のhoge1の行に対して置換を実行します
そして次に評価する行はhoge2の行になります
hoge2が評価されるとhoge3の行に対して置換が実行されるので評価が飛ばされます
そしてその次はhoge4が評価される、といった挙動になります
なので結果として飛び飛びの結果になった感じです

今回の目的は該当する各行に対して追記ことなのでNコマンドはそもそもユースケースに合わないと思います
じゃあなんで紹介したんだと言われると、たまたま見つけちゃったのでどうせなら紹介しちゃおうかなと思ったからです

あと今回は上書きしてないですが、上書きしたい場合は「-i」オプションを付ければOKです

0 件のコメント:

コメントを投稿