本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、「sed」コマンドの応用編です。
本連載では、Linuxの基本的なコマンドについて、基本的な書式からオプション、具体的な実行例までを分かりやすく紹介していきます。今回は「sed」コマンドの応用編を解説します。
「sed」は「Stream EDitor」の略で、「sed スクリプトコマンド ファイル名」で、指定したファイルをコマンドに従って処理し、標準出力へ出力します。ファイル名を省略した場合は、標準入力からのデータを処理します。sedコマンドでは、パイプとリダイレクトを活用するのが一般的です。
sedコマンドの主なオプションは次の通りです。
短いオプション | 長いオプション | 意味 |
---|---|---|
-r | --regexp-extended | スクリプトで拡張正規表現を使用する |
-e スクリプト | --expression=スクリプト | スクリプト(コマンド)を追加する |
-f スクリプトファイル | --file=スクリプトファイル | 実行するコマンドとしてスクリプトファイルの内容を追加する |
-i | --in-place | ファイルを直接編集する |
-i拡張子 | --in-place=拡張子 | ファイルを直接編集し、指定した拡張子でバックアップする(※「-i」と「拡張子」の間には空白を入れない) |
--follow-symlinks | -iで処理する際にシンボリックリンクをたどる | |
-n | --quiet,--silent | 出力コマンド以外の出力を行わない(デフォルトでは処理しなかった行はそのまま出力される) |
-l 文字数 | --line-length=文字数 | lコマンドの出力行を折り返す長さを指定する(※「-l」と「文字数」の間には空白を入れる) |
-s | --separate | 複数の入力ファイルを一続きのストリームとして扱わずに個別のファイルとして扱う |
-u | --unbuffered | 入力ファイルからデータをごく少量ずつ取り込み、頻繁に出力バッファーをはき出す |
-z | --null-data | NUL文字で行を分割する(通常は改行で分割) |
--posix | 全てのGNU拡張を無効にする | |
sedでは、「アドレス」と「コマンド」の組み合わせで処理を指定します。
アドレスには行番号や正規表現による指定が可能で、省略した場合は全ての行が処理の対象となります。
コマンド | 意味 |
---|---|
= | 現在の行番号を出力する |
a テキスト | テキストの追加。指定した位置の後ろに[テキスト]を挿入する(挿入するテキストに改行を含める場合は、改行の前にバックスラッシュを置く) |
i テキスト | テキストの挿入。指定した位置の後ろに[テキスト]を挿入する(挿入するテキストに改行を含める場合は、改行の前にバックスラッシュを置く) |
c テキスト | 選択した行を[テキスト]で置換する(挿入するテキストに改行を含める場合は、改行の前にバックスラッシュを置く) |
q | これ以上入力を処理せずに終了する(未出力分があれば、出力してから終了する) |
Q | これ以上入力も出力もせずに終了する |
d | 指定した行を削除する |
p | 処理した内容を出力する(「-n」オプション指定時は「p」コマンドがないと何も出力されなくなる) |
s/置換前/置換後/ | [置換前]で指定した文字列にマッチした部分を[置換後]に置き換える。複数マッチした場合は先頭のみ置換、全てを置換したい場合は、「s/置換前/置換後/g」のように「g」オプションを指定する |
y/元の文字列/対象文字列/ | [元の文字列]にあるものを、対象文字列の同じ位置にある文字に置換する(「tr」コマンドのように使用できる) |
# | コメント(スクリプト中、「#」以降がコメントとなる) |
文字列の置き換えは、「s/置換前/置換後/」で行います。例えば、「s/jpg/jpeg/」で「jpg」を「jpeg」に置き換えることができます。
置き換え対象の文字列には、正規表現を使用することができます。例えば、ファイル名の拡張子部分の「jpg」を置換対象にするのであれば、「行末にある.jpgを.jpeg」と考えて、「s/\.jpg$/.jpeg/」とします。
「$」は「行末」を示す正規表現です。また、「.」は正規表現で「任意の1文字」という意味なので、「\」で意味を打ち消し「\.」で“「.」という文字そのもの”としています。
なお、「\」記号はシェルでも特殊文字の意味を打ち消す(エスケープ)の意味があるため、引用符が必要です。
ls | sed s/jpg/jpeg/
(「jpg」を「jpeg」に置き換える)
ls | sed "s/\.jpg$/.jpeg/"
(行末の「.jpg」(拡張子.jpg)を「.jpeg」に置き換える(引用符が必要))(画面1)
※「ls」コマンドは、画面出力時は複数行(マルチカラム)で出力、パイプやリダイレクトでは1件1行で出力されますが、本稿に掲載した画面は結果を見やすくするために「-1」オプションで常に1件1行出力するように指定しています。
「(〜)」を使うと、文字列の一部を取り出すことができます。
置換前の指定で取り出したい部分を「(〜)」で囲み、置換後の指定で「\1〜\9」を使って取り出します。「\1」は1つ目「()」部分、「\2」は2つ目の「()」部分に対応します。また、対象となった行全体は「&」で参照できます。
なお、「()」は拡張正規表現なので、「\(」「\)」のように「\」を付けるか、「-r」オプション付きで実行する必要があります。
ls | sed -r "s/(.*)\.jpg$/& \1.jpeg/"
(元の文字列と、行末の「.jpg」(拡張子.jpg)を「.jpeg」に置換したものを並べる)(画面2)
置換後の文字列がコマンド列となるように加工し、パイプで「bash」に渡すことで、コマンドを実行することができます。
先ほどの置換を「mv image1.jpg image1.jpeg」のようになるように変更して、「-n」オプションと「s」コマンドの「p」オプションで置換処理を行った行だけを出力すると、次のようになります。
ls | sed -rn "s/(.*)\.jpg$/mv & \1.jpeg/p"
(「mv ファイル名 新ファイル名」となるように置換する)(画面3)
この結果をパイプでbashに渡すことで、「mv」コマンドが実行されます。
ls | sed -rn "s/(.*)\.jpg$/mv & \1.jpeg/p" | bash
(置換した結果をbashに渡す)(画面4)
PC-9801N/PC-386MからのDOSユーザー。1992年より生産管理のパッケージソフトウェアの開発およびサポート業務を担当。のち退社し、専業ライターとして活動を開始。著書に『図解でわかるLinux』『らぶらぶLinuxシリーズ』『はじめてでもわかるSQLとデータ設計』『シェルの基本テクニック』など。2011年より、地方自治体の在宅就業支援事業にてPC基礎およびMicrosoft Office関連の教材作成およびeラーニング指導を担当。
Copyright © ITmedia, Inc. All Rights Reserved.