Linuxコマンド - sed

提供:MochiuWiki : SUSE, EC, PCB
2021年2月10日 (水) 11:39時点におけるWiki (トーク | 投稿記録)による版 (→‎文字列の削除)
ナビゲーションに移動 検索に移動

概要

sedコマンドとは、与えられた文字列をルールに従って変換するコマンドである。
例えば、文字列の置換や行の削除といった処理が行う。

変換に利用できるルールにおいて、下表のような条件式が利用できる。
例えば、文字列を挿入したい場合は、aiの後に挿入する文字列を指定する。
文字列を置換したい場合は、s/置換ルール/置換文字/と実行する。

置換ルールの最初に数値を指定すると、指定した行のみが処理される。
例えば、3dと指定すると、3行目が削除される。

sedコマンドで実際に変換を行う場合は、変換処理内容は-eオプションを指定した後に記述する。
また、sedコマンドに指定したファイルの内容を処理する。
例えば、test.txt内にある"Linux"を"リナックス"に置換する場合は、次のように実行する。

sed -e "s/Linux/リナックス/g" test.txt 


結果は標準出力に表示される。
もし、ファイルに保存する場合はリダイレクトを利用する。

また、-fオプションで変換手順を記載したスクリプトファイルを指定できる。その時、指定したファイルの内容に従って処理される。


構文

sed <オプション> <対象ファイル>


オプション 説明
-e <スクリプト名> 指定したスクリプト(条件式)で変換処理を行う。
-f <ファイル名> 指定したファイルに記述されているコマンドやスクリプトに従って処理を行う。
r 指定したファイルに記述されているコマンドやスクリプトに従って処理を行う。



パターン・スペースとホールド・スペース

sedコマンドでは、処理を行う対象の文字列を一時的に保存しておく必要がある。
この保存スペースのことをパターン・スペースと呼ぶ。
例えば、1行目を処理する時には、1行目の内容がパターン・スペースに保存される。その後、パターン・スペースにある文字列に対して置換などの処理が行われる。

ホールド・スペースとは、パターン・スペースのサブとして使われる保存領域である。
例えば、パターン・スペースにある文字列を後の処理で利用する場合等は、一度ホールド・スペースに移動しておく。
他の処理を行った後に、ホールド・スペースからパターン・スペースに戻せば、以前の処理の続きが行うことができる。

パターン・スペースの文字列をホールド・スペースにコピーする場合はh
ホールド・スペースの文字列をパターン・スペースにコピーする場合はg
パターン・スペースとホールド・スペースを入れ替える場合はxを実行すればよい。


sedコマンドの条件式

条件式 説明
行数 処理する行数を指定する
行数,行数 指定した行数間の文字列を処理する。
$を指定すると最後の行を表せる。
/文字列/ 指定した文字列が現れる行を処理する。
先頭に^を付けると、指定した文字列から始まる行、末尾に$を付けると指定した文字列で終わる行が対象になる。
行数の範囲指定でも利用できる。
:ラベル bおよびtコマンド用のラベル
#コメント コメント
{..} 括弧内をブロックとして扱う。
= 現在の行番号を表示する。
a <文字列> 文字列を追加する。ただし、改行をする場合は、直前に\を付ける。
i <文字列> 文字列を挿入する。ただし、改行をする場合は、直前に\を付ける。
q 処理を中断して、sedコマンドを終了する。
r <ファイル名> 指定したファイルを読み出して追加する。
b <ラベル> 指定したラベルに移動する。
t <ラベル> s///が成功した場合、指定したラベルに移動する。
c <文字列> 選択している行を文字列に置換する。ただし、改行をする場合は、直前に\を付ける。
d パターン・スペースを削除する。
D パターン・スペース内の最初の改行までを削除する。
h パターン・スペースをホールド・スペースにコピーする。
H パターン・スペースをホールド・スペースに追加する。
g ホールド・スペースをパターン・スペースにコピーする。
G ホールド・スペースをパターン・スペースに追加する。
x ホールド・スペースとパターン・スペースを入れ替える。
n 次の行をパターン・スペースに読み込む。
N 次の行をパターン・スペースに追加する。
p 現在のパターン・スペースを表示する。
P 現在のパターン・スペースの最初に現われる改行までを表示する。
w <ファイル名> 現在のパターン・スペースを指定したファイルに書き込む。
s/置換条件/置換文字/ 置換条件を置換文字に変換する。
最後にgを付けた場合は、置換条件に当てはまる全ての文字列が置換される。
y/変換対象の文字/変換文字/ 変換対象の文字を変換文字に変換する。



使用例

テキストファイルの5~10行目を削除する。

sed -e "5,10d" test.txt 


テキストファイル内の"Nikkei Linux"を"日経Linux"に変換する。

sed -e "s/Nikkei Linux/日経Linux/g" test.txt 


"Error"という文字列がある行に対して、"### Check Line ###"という新しい行を追加する。

sed -e "/Error/i #### Check Line ###" test.txt



正規表現

sedコマンドは、多くの正規表現を使用することができる。
ただし、sedコマンドの正規表現の記述方法は、他のプログラム言語の正規表現はやや異なっているので注意する。

下表に、sedコマンドで使用できる正規表現を示す。
併せて、grepコマンドとawkコマンドの正規表現も記載する。

grep sed awk 意味
. . . 任意の1文字
* * * 直前の1文字または1パターンの0回以上の繰り返し
^ ^ ^ 行の先頭
$ $ $ 行の末尾
\( \) \( \) () パターンのグループ化
\1 \2 \3 \1 \2 \3 後方参照
[ ] [ ] [ ] 括弧内の任意の1文字
\{n\} \{n\} {n} 直前の1文字または1パターンのn回の繰り返し
\{n, \} \{n, \} {n, } 直前の1文字または1パターンのn回以上の繰り返し
\{n, m\} \{n, m\} {n, m} 直前の1文字または1パターンのn回以上かつm回以下の繰り返し
\+ \+ + 直前の1文字あるいは1パターンの1回以上の繰り返し
\? ? 直前の1文字あるいは1パターンの0回または1回だけ出現
\| \| | 2 パターンのうちどちら片方
.* 空文字("")を含む任意の文字列
[aA0] aもしくはAもしくは0
[^aA0] aでもAでも0でもない文字
[a-z] aからzまでのいずれかの文字
^$ 空行



sedコマンドを使用したフィルタリング

フィルタとは

フィルタとは標準入力からデータを受け取り、そのデータを加工した上で標準出力に出力する機能のことである。
この機能には、主に、sed、awk、tr、grep等のコマンドが使用され、それらのコマンドに|(パイプ)でデータを受け渡すことでフィルタ機能を実現する。
(例: パイプを使用して不必要な文字列を消去する処理や適切な位置に文字列を付加する処理)

以下のような処理には、フィルタを使用すると効率的に作業ができる。

  • コマンドの実行結果から、次のコマンドのパラメータを生成する。
  • あるファイルを決まったパターンで編集する。
  • 膨大な文字数のログファイル内から必要な情報のみを抜き出す。


パイプでフィルタに加工するデータを受け渡し、目的とする文字列を抽出するフィルタリングを行う。
フィルタをパイプで複数連結することで、より複雑なフィルタリング処理を実現することができる。

command | filter
command | filter1 | filter2
command | filter1 | ... | filterN


文字列Aを文字列Bに置換する

sedコマンドは様々な機能を持つコマンドであるが、主に、文字列の置換処理に利用されるコマンドである。

置換処理を行う場合、置換対象と置換後の文字列を指定してコマンドを実行する。
置換対象の指定には、正規表現を使用することも可能である。
ただし、一部の正規表現は使用できない。また、sedのバージョン等により、使用できる正規表現も異なる。

各行の最初に一致した文字列のみ置換する。

sed -e 's/パターン1/パターン2/'  # 各行の最初に一致したパターン1をパターン2に置換する


gの指定が無い場合、各行の最初に一致した文字列のみが置換対象となる。
同一行内に複数の一致があった場合でも、2つめ以降の一致した文字列は置換されない。

echo "hogehoge" | sed -e 's/hoge/fuga/'  # 文字列"hogehoge"の"hoge"を"fuga"に置換する
                                         # 実際に置換されるのは、先頭の"hoge"のみ
fugahoge


一致したすべての文字列を置換するには、g(globally)を指定する。

sed -e 's/パターン1/パターン2/g'  # sedコマンドの置換パターンにgを指定する


gを指定すると各行の最初に一致した文字列のみではなく、すべての一致する文字列を置換対象とする。

echo "hogehoge" | sed -e 's/hoge/fuga/g'  # gを指定して実行することで、全ての"hoge"が"fuga"に置換される
fugafuga


アルファベットの大文字小文字を区別しない。

sed -e 's/パターン1/パターン2/i'  # iを指定することで大文字小文字の区別を行わない


iを指定する場合、アルファベットの大文字小文字を区別しない置換処理を行う。
例えば、パターン1に"a"を指定する時、"a"と"A"が置換対象となる。

echo "HogeHoge" | sed -e 's/hoge/fuga/i'  # iを指定することで、大文字小文字を区別することなく置換処理が行われる
fugaHoge

echo "HogeHoge" | sed -e 's/hoge/fuga/gi'  # 上記のように、iとgを同時に指定することもできる
fugafuga


複数パターンの置換を連続して行うには、-eオプションで複数の置換パターンを連結して指定する。

sed -e 's/パターン1/パターン2/' -e 's/パターン3/パターン4/'


以下の例では、各行最初に一致したパターン1をパターン2に置換後、
さらにパターン3をパターン4に置換するといった複数の置換を連続して実行している。

echo "hogehoge fugafuga" | sed -e 's/hoge/foo/g' -e 's/fuga/bar/g'  # "hoge"を"foo"に置換した後、さらに、"fuga"を"bar"に置換する
foofoo barbar

echo "hogehoge fugafuga" | sed -e 's/hoge/foo/g' -e 's/fuga/bar/g' -e 's/ /-/g'  # 上記に加えて、スペースをハイフンに置換する
foofoo-barbar

echo "hoge" | sed -e 's/hoge/fuga/' -e 's/fuga/foo/' -e 's/foo/bar/'  # "hoge"を次々に置換して、最終的に"bar"にしている
bar


パターン指定の区切り文字を変更する。
パターン指定の区切り文字には、任意の文字を使用することができる。

sedコマンドは、sの直後に指定した文字を区切り文字として認識するため、使用する区切り文字は/(スラッシュ)でなくともよい。
特に /自体がパターンに含まれる場合は、/の代わりに%や|等を区切り文字に使用すると、/をエスケープする必要がなくなる。
これは、大変便利なテクニックであるため、是非覚えておくこと。

sed -e 's%パターン1%パターン2%'
sed -e 's|パターン1|パターン2|'
sed -e 's:パターン1:パターン2:'


以下の例では、/を区切り文字にする場合、/がパターンに含まれる場合はエスケープする必要がある。
これを、/以外の区切り文字に変更して実行している。(可読性の面で、大変有利である)

echo "hoge/hoge" | sed -e 's/hoge\/hoge/fuga\/fuga/'
fuga/fuga

echo "hoge/hoge" | sed -e 's%hoge/hoge%fuga/fuga%'
fuga/fuga

echo "hoge/hoge" | sed -e 's|hoge/hoge|fuga/fuga|'
fuga/fuga

echo "hoge/hoge" | sed -e 's:hoge/hoge:fuga/fuga:'
fuga/fuga


単一置換パターン指定であれば、-eオプションは省略できる。

sed 's/パターン1/パターン2/'


複数の置換パターンを指定しない場合は、-eオプションは省略できる。
ただし、省略しても問題なく機能するが、後から他のパターンを追加するような場合もあるので、常に指定することを推奨する。

echo "hoge" | sed 's/hoge/fuga/'
fuga


文字列の削除

特定の文字列を削除するには、置換後のパターンに空文字を指定する。
これにより、置換対象パターンと一致する文字列は空文字に置換されるため、結果的に削除と同等の処理となる。

各行の最初に一致したパターンを削除する。

sed -e 's/パターン//'


全てのパターンを削除する。

sed -e 's/パターン//g'  # 置換後の文字列を指定しないことで削除処理になる


文字列の削除も置換処理と同じなので、通常の置換処理と使い方は同じである。

echo "hoge-fuga foo-bar" | sed -e 's/-//'  # gを指定していないため、最初に一致した文字のみ削除される
hogefuga foo-bar

echo "hoge-fuga foo-bar" | sed -e 's/-//g'  # gを指定すると、全ての一致する文字列が削除される
hogefuga foobar



正規表現を使用した文字列置換

置換対象パターンの指定には、一部の正規表現を使用することもできる。
使用可能な正規表現は、sedのバージョン等により異なる場合がある。

aからeまでのいずれかの文字をXに置換する。

echo "abcdefghij" | sed -e 's/[a-e]/X/g'
XXXXXfghij


数字以外を削除する。

echo "I am 20 years old." | sed -e 's/[^0-9]//g'
20


行頭に文字列を追加するには、行頭を表す^(キャレット)を追加する文字列に置換する。

echo "Hello World" | sed -e 's/^/>>>/g'
>>>Hello World


行末に文字列を追加するには、行末を表す$を追加する文字列に置換する。

echo "Hello World" | sed -e 's/$/ !!!/g'
Hello World !!!


連続する複数のスペースを1つにまとめる。
連続する複数のスペースは、 *で表される。

*(アスタリスク)は直前の文字の0〜N個の繰り返しであるため、 *では0個のスペースも置換対象とみなされる。
したがって、連続する複数のスペースを表すには、"1個のスペース + 0〜N個のスペース"で *となる。

echo "hello     world" | sed -e 's/  */ /'
hello world


GNU sed(Linuxのsed)では、 \+で、1個以上の連続するスペースを表現することができる。

echo "hello     world" | sed -e 's/ \+/ /'
hello world