LoginSignup
14
16

More than 5 years have passed since last update.

sed 中級者への道

Last updated at Posted at 2015-09-08

区切り文字は何でもよい。

文字を置換するとき、一般的には"/(スラッシュ)"を区切り文字にすることが多い。

sed 's/old/new/' <old_file >new_file

ただし、ファイルパスなど"/(スラッシュ)"を含む文字を置換したい場合は、スラッシュを区切り文字にしていると、いちいちエスケープしなくてはならず、読みづらい。

sed 's/\/usr\/local\/bin/\/common\/bin/' <old_file >new_file

sedは"s"の次の文字を区切り文字にしてくれるため、以下のように書くことが可能になる。

sed 's_/usr/local/bin_/common/bin_' <old_file >new_file

sed 's:/usr/local/bin:/common/bin:' <old_file >new_file

"&"でマッチした文字列を表現する。

マッチした文字列を置換後も出力したい場合がある。その時は、置換後の表現で"&"を使うと、マッチした文字列を出力してくれる。

例:a-zを使った単語をカッコつきで出力する。
sed 's/[a-z]*/(&)/' <old_file >new_file

例:数字部分を2度出力する。
sed 's/[0-9]*/& &/' <old_file >new_file

"\(数字)"でマッチした文字列を表現する。

カッコ付きでマッチさせた文字列を"\(数字1-9)"で使用することができる。(なんのこっちゃ)

例:各行の先頭の単語だけ出力したい。
sed 's/\([a-z]*\).*/\1/' <old_file >new_file

ちょっと解説
正規表現ではカッコ"()"を使うとマッチングした文字をグルーピングすることができる。
そのグルーピングした部分が、\1 に対応する。
sedでは、"()"はエスケープさせないと文字のカッコと認識されてしまうのでエスケープしておいて、
その中に含まれる [a-z]* が \1 に対応することになる。

例:2つの単語の順序を入れ替えたい。
sed 's/\([a-z]*\) \([a-z]*\)/\2 \1/' <old_file >new_file

2つめのカッコは \2 に対応する。

例:同じ単語が続けて出力されている場合、1つを削除する。
sed 's/\([a-z]*\) \1/\1/' <old_file >new_file

"\(数字)"はマッチング文字列としても使える。

例:先頭の文字の並び順を入れ替える。(abcをcbaにする)
sed 's/^\(.\)\(.\)\(.\)/\3\2\1/' <old_file >new_file

マッチした行の次の行を置換する。

「N」で次の行も読み込んで、置換ができる。

例:「target」にマッチした行の次の行も読み込んで、置換する。
sed '/target/N;s/old/new/' <old_file >new_file

例:「target」にマッチした行の次の行も読み込んで、改行を削除する。
sed '/target/N;s/\n//' <old_file >new_file


随時追加予定です。

参考

14
16
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
14
16