【Linux入門】sedコマンドの基本を学ぶ

ファイル処理の際に大量のデータを加工したり・抜き出したりする場面は多いと思います。そこでよく使われるのがsedコマンドです。sedコマンドは充実した置換機能が魅力ですが、書式がやや特殊(?)なので初心者には少しとっつきにくいコマンドでもあります。

本稿ではsedコマンドの使い方を丁寧に解説します。


目次

sedコマンドの用法
sedコマンドで指定した行を表示する
 ・「最終行から上にn番目の行」?
sedコマンドで文字列を消去
sedコマンドで文字列を置換
 ・「’」と「”」の使い分け
 ・置換したい文字列が「/」を含むとき
 ・「&」や「\」で置換したいとき
sedコマンドで文字列(行)を追加・挿入
 ・該当行or指定行の先頭or末尾に文字列を追加する
 ・特定の文字列を含む行を丸ごと置換したいとき
Tips1:空行を削除する
Tips2:複数の置換を同時に行う


 sedコマンドの用法

sedコマンドの基本的な使い方は以下のようになります。

 

 

(※「$ 」はコマンド受付中のマークです。既に表示されているので皆さんが入力する必要はありません(環境によっては「# 」になっているかもしれません))

スクリプトとは「アドレスとコマンドを並べて書いたもの」のことであり、行番号または正規表現を指しています。要するにどの行に対してどのような操作をするのか、ということを指定するのがスクリプトです。この辺りは習うより慣れた方が良いと思いますので、具体的な使い方を見ていきましょう。

 

 sedコマンドで指定した行を表示する

それでは「kawa.txt」というデータセットを用いて使用法を見ていきましょう!

実際にコマンドを試してみたい方のために流路延長Top10の河川名と延長、流域面積のリストを作りましたので、必要に応じてご活用下さい。

» 流路延長Top10河川のリスト

» 閉じる

sedコマンドを使えば「5行目を表示する」のような操作が可能です。例えばkawa.txtというファイルの5行目を表示するには以下のようにします。

 

 

出力を制限する「-n」オプションを追加してアドレスを指定すると、マッチした行だけが出力されます(デフォルトでは処理されなかった行がそのまま出力されます)。ここで “p” は「出力」を意味する “print” の頭文字です。

同様にして「5~8行目を表示する」という操作も可能です。

 

 

アドレスを「\$」とするとファイルの最終行が表示されます。「$」は最後の番号を意味し、シングルクォーテーションを使わない場合はバックスラッシュで「$」をエスケープする必要があります。

 

 

シングルクォーテーションには中身の文字をそのまま単なる文字列として扱う機能があるため、アドレス指定の部分をシングルクォーテーションで囲んで「’$p’」とすればバックスラッシュは不要です(「’\$p’」とするとエラーになります)。

なお、このコマンドはtailコマンドで行数を指定して出力させた場合と同じです。

 

(↑同じ出力)

grepコマンドでは行数を指定して出力させる操作が難しいので、そういうときはsedコマンドが活躍します。

 

「最終行から上にn番目の行」?

例えば、最終行から上の4行を消去・置換したいなどというとき、「$」が最終行の行番号を表すからといって安直に「$-4」などとしてはいけません。動きません。

 

 

とするとkawa.txtというファイルに改行コードが何個存在するかを出力してくれるので、+1すれば行数になります。これを使ってシェルを書くなり何なりする必要があります。

 

因みに単に表示したいだけならtailコマンドを用いて「tail -n 4 kawa.txt」とすれば事足ります。

 

 sedコマンドで文字列を消去

sedコマンドに最も期待されている機能が文字列の置換と消去でしょう。消去のコマンドは比較的簡単で、これまで見てきた「p」コマンドの部分を「d」(delete)に変えるだけです。

 

 

このとき、「-n」は付けないことに注意しましょう。「-n」オプションはsedコマンドによって何らかの処理が施された行のみを表示するオプションであるため、消去した行を表示しようとしても何も表示されません。

ここで注意して頂きたいのが、このコマンドを使ったからといって「kawa.txt」というファイルの中身は何ひとつ変わっていない、ということです。dコマンドは出力でのみ特定文字を含む行を消去するという機能をもっています。

もし元ファイルの中身を変える、つまり、上書きしたいときは「-i」オプションを利用します。

 

 

catコマンドでkawa.txtの中身を見てみると、ちゃんと “teshio” の行が無くなっていますね。上書きするために「-i」オプションを利用することはそれなりにありますが、元のファイルの行数などが変わるので使いどころには気を付ける必要があります。

このdコマンドはpコマンドと同様に複数行にわたって適用できます(※練習の際はkawa.txtの中身は作り直すか、コピーしてお使い下さい・・・)

 

 

確かに5~8行目が除かれていますね。

「-i」オプションで上書きできると説明しましたが、それならリダイレクトでも上書きできるのではないか、と思った方もいるかもしれません。コマンドによっては同時に読み書きできるものもあるかもしれませんが、sedの場合、ファイル(もしくは標準入力)の読み込みと同時に出力されるので、以下のようにリダイレクトするとファイルの中身が消えてしまいます。

 

 

このように何もでてきません。初心者のうちはsedで色々いじる前に対象ファイルのバックアップを取っておくことを強くお勧めします。

 

 

 sedコマンドで文字列を置換

sedコマンドで置換する際の基本的な書式は以下のようになります。

 

 

“s” というコマンドは英語で「置換」を意味する “substitute” 表しています。これを使って “km” を “kilometer” に置換してみましょう。

 

 

すべての行で “km” → “kilometer” と置換されていますね。しかしすべての”km”が置換されている訳ではなく、”km” という文字列を含む行の最初の “km” だけが置換されています。2回目に出てきた “km” を置換するときはコマンドの最後に「2」を付けます。

 

 

また、すべての該当する文字列を置換するには

 

 

というようにコマンドの最後に「g」を付けます。

 

 

すべての “km” が置換できましたね。

見栄えに配慮して、数字と単位の間にスペースを入れたいときもsedコマンドが活躍します。

 

 

このとき、置換後の文字列に空白が含まれるため、ダブルクォーテーション(またはシングルクォーテーション)で囲んでおく必要があります。もし囲んでいないと “s/km/” と “km/g” が別々のオプションと見なされてしまい、正しく作動しません。

●   ●   ●

・「’」と「”」の使い分け

ダブルクォーテーションとシングルクォーテーションの使い分けは、中身の文字がシェルにとって意味があるもの(予約文字など)かどうかで決まります。

例えば、河川名の後に変数で指定した文字列を入れたいときはどちらで囲むかで結果が変わってきます。ここでは例としてsetコマンドで「ex」という名前の変数に “-gawa” という文字列を入れています。

(ダブルクォーテーションを使った場合)

 

(シングルクォーテーションを使った場合)

 

このように、シングルクォーテーションは中身を文字列としてしか扱わないので「${ex}」は変数ではなく単なる文字列として出力されてしまっています。

「’」と「”」にはそれぞれどのような特徴があるのかをしっかり理解しておかないと、思わぬバグの原因になってしまうこともあるので要注意です。

●   ●   ●

・置換したい文字列が「/」を含むとき

今まで紹介してきたsedコマンドの置換の書式は、

 

 

のように、「/」によって区切られていましたが、特にスラッシュである必要はありません。「@」や「#」などでも代用できますし、「a」や「1」のような英数字でも区切ることが可能です。

(「@」の場合)

(「#」の場合)

(「a」の場合)

 

使えない文字としては特殊文字の「!」や「$」などでしょうか。ただ、ほとんどの文字で代用可能なので、検索対象や置換後の文字列にスラッシュが含まれている場合は区切り文字を「/」以外のあまり紛らわしくない文字にしましょう。

●   ●   ●

・「&」や「\」で置換したいとき

「&」(アンド)はsedのオプション中では検索で該当した文字列を表しており、「\」(バックスラッシュ)は特殊文字をエスケープするための記号なので、単体では表示できません。

これらの文字は「\&」や「\\」のようにエスケープしておく必要があります。

(例)

 

意外と忘れやすく、バグの原因になることがあるので注意です。

 

 

 sedコマンドで文字列を追加・挿入

sedコマンドでは文字列を任意の場所に追加したり挿入したりすることができます。「i」は挿入(前の行に入れる)、「a」は追加(後ろの行に付け足す)を意味します。行番号を指定しなければすべての行が操作対象となります。

 

※行頭の空白はスペースをエスケープすることで表示できます。

 

 

●   ●   ●

・該当行or指定行の先頭or末尾に文字列を追加する

正規表現の「^」は行頭、「$」行末を表します。環境によっては「-e」オプションは付けなくても動きますが、付けておいた方が無難です。

(行指定なしバージョン)

 

(行指定ありバージョン)

 

(末尾:行指定ありバージョン)

●   ●   ●

・特定の文字列を含む行を丸ごと置換したいとき

特定の文字列を含む行全体を置換するにはcコマンドを使います。

 

(3行目を “ishikari” が大文字である行に置換しました)

 

 Tips1:空行を削除する

行頭から行末まで何もないような行を検索すればよいので次のような記法になります。(※ここで「^」は行頭、「$」は行末の意味)

 

 

 Tips1:空行を削除するTips2:複数の置換・追加を同時に行う

「-e」オプションによるコマンドを複数個併記すると並列的に置換・追加できます。

 

 


以上、sedコマンドの様々な機能を紹介してきましたが、これだけ豊富な編集機能が備えているということを知っていれば「sed」が「stream editor」の略だというのも頷けますね!

sedコマンドは使い方次第ではファイル処理作業を劇的に省力化してくれます。今回紹介していないオプションや使用法も沢山ありますので、是非勉強してみてください!

 

 

“【Linux入門】sedコマンドの基本を学ぶ” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です