文字列置換で使われるsed(stream editor)はストリームエディタと呼ばれるコマンドの一種です。入力ストリームに対してスクリプト処理を行います。オプションを使いこなせば複雑な置換やファイル処理が実行できます。
sed オプション
-r | 拡張正規表現を使用する(デフォルトでは基本正規表現が使われる) |
-e スクリプト | スクリプトコマンドを使用する (オプションを指定しない場合、最初の引数がスクリプトとしてみなされる。 -eは複数のスクリプトを指定するときに使われる) |
-f ファイル | スクリプトファイルを使用する |
-i ” (OS X) -i” (Ubuntu) | ファイルを編集して上書きする ‘拡張子’を入れると、入力ファイル名.拡張子の名前でバックアップが保存される |
-z (–null-data) | null文字で行を分割する |
sed sコマンド(文字列置換)
s/置換前の文字列(正規表現)/置換後の文字列/g
*gがないと、各行1回しか置換が行われない
通常sedコマンドは処理した結果を標準出力に出力するだけで元の入力はいるは変化しません。
次の例は、 lsコマンドの結果を-eオプションを使って置換した結果が標準出力されていますが、元のファイル名が置き換わることはありません。
$ ls #2つのファイルを用意します
sample1.txt sample2.txt
$ ls | sed -e 's/sample/test/g' -e 's/txt/csv/g' #置換1 sample-->test, 置換2 txt-->csv
test1.csv
test2.csv
$ ls #↑で、置換処理の結果を標準出力しているが、元のファイル名が置き換わっているわけではない
sample1.txt sample2.txt
ファイルの中身を置換してみます。
$ cat test.properties #test.propoertiesというファイルを用意しました
key1=value1
key2=value2
key3=value3
$ sed 's/value1/banana/g' test.properties #置換結果を標準出力します
key1=banana
key2=value2
key3=value3
$ cat test.properties #元ファイルの中身は変更されていません
key1=value1
key2=value2
key3=value3
$ sed 's/value1/banana/g' test.properties > replace.txt #置換した結果を別ファイルにリダイレクトします
$ cat replace.txt #置換後のファイルが作成されました
key1=banana
key2=value2
key3=value3
-iオプションを使って直接ファイルの中身を書き換えてみましょう。下記はMac OSの場合の例です。
$ cat test.properties #test.propoertiesというファイルを用意しました
key1=value1
key2=value2
key3=value3
$ sed -i '' 's/value1/apple/g' test.properties #''に拡張子を指定しない場合は、バックアップファイルを作成しない
$ cat test.properties #ファイルの文字列が書き換わりました
key1=apple
key2=value2
key3=value3
$ sed -i '.bak' 's/value2/orange/g' test.properties #バックアップファイルを作成しつつ、置換する
$ cat test.properties.bak # バックアップファイルの中身確認(置換前)
key1=apple
key2=value2
key3=value3
$ cat test.properties # 元ファイルは上書き置換されている
key1=apple
key2=orange
key3=value3
正規表現をつかう
「.」は任意の1文字を意味します。下記の例で「…」としているのは任意の3文字が置換前の文字列になります。でもこれだとどこをとっても任意の3文字じゃないか!っとなりそうですが、スクリプトの最後に「g」がついていないので、各行に1回だけ。つまり、各行の先頭の任意の3文字が置換前の文字列になります。そして、「&」は「…」に相当する文字列を意味します。
$ cat country.txt #country.txtというファイルを準備しました
JPN001
USA002
CHN003
$ cat country.txt | sed 's/.../&-/' #国名と番号の間に「-」を挿入します
JPN-001
USA-002
CHN-003
範囲を指定して置換する
sed ‘開始行,終了行s/置換前文字列/置換後文字列/’
置換範囲を行指定することも可能です。
$ cat sample.txt # sample.txtを準備
1 apple
2 orange
3 banana
4 strawberry
5 pineapple
6 kiwi
$ sed '2s/[0-9]/x/' sample.txt # 2行目の数値をxに置換する
1 apple
x orange
3 banana
4 strawberry
5 pineapple
6 kiwi
$ sed '2,4s/[0-9]/x/' sample.txt # 2~4行目の数値をxに置換する
1 apple
x orange
x banana
x strawberry
5 pineapple
6 kiwi
$ sed '3,$s/[0-9]/x/' sample.txt # 3~最後の行までの数値をxに置換する
1 apple
2 orange
x banana
x strawberry
x pineapple
x kiwi
コメント