Linux

速習Linux – 文字列の置換・抽出・検索と正規表現【sed・awk・grep】

この記事では、Linux環境で強力なテキスト処理ツールであるsedコマンド、awkコマンド、grepコマンドの詳細な解説を行います。sedコマンド、awkコマンド、grepコマンドコマンドの基本的な使い方から、使用例、正規表現の基礎までを紹介した完全ガイドです。

sedコマンド

sed(Stream Editor)は、テキストストリームの編集に特化した強力なツールです。以下にsedコマンドの基本的な構文を示します。

sed [オプション] 'スクリプト' ファイル名
  1. オプション: sedコマンドの挙動を制御するための指定です。例えば、置換を行う場合には-eオプションを使用します。
  2. スクリプト: 実行したいsedコマンドの操作を指定します。置換や削除、追加など、様々な編集操作が可能です。
  3. ファイル名: 処理を行いたいテキストファイルのパスを指定します。省略した場合は標準入力から読み込みます。

以下でもう少し詳しく解説します。

コマンド

どういう処理をしたいかをコマンドで指定します。

処理内容の出力、削除、文字列の追加、置換などの処理を行えるコマンドが用意されています。

コマンド説明
[=]現在の行番号を出力します。
[#]コメント
[a 文字列]指定した位置の後ろに文字列を追加します。(改行する場合は改行前の文字列に[/]を付ける。)
[i 文字列]指定した位置の後ろにテキストを挿入します。(改行する場合は改行前の文字列に[/]を付ける。)
[c 文字列]選択した行をテキストに置き換えます。(改行する場合は改行前の文字列に[/]を付ける。
[q]入力を中断し、それ以上処理を行わず終了します。(※未出力分があれば出力してから終了します。)
[Q]入力、出力をせずに終了します。
[d]指定した行を削除します。
[l 文字数]指定した文字数で改行します。
[p]処理した内容を出力します。-n オプションと組み合わせて使うことがあります。
[P]処理した内容を出力します。
[r ファイル名]ファイルを先頭に追加します。
[s/置換前文字列/置換後文字列/](置換前文字列)で指定した文字列にマッチした部分を置換後文字列へ置き換えます。また複数マッチした場合は先頭のみ置換を行い、対象全て置換を行う場合は[s/置換前/置換後/g]のように[-g]オプションを併用します。
[y/元の文字列/対象文字列/](元の文字列)のものを(対象文字列)の同じ位置に存在する文字列に置換します。(※[tr]コマンドのように使用可能です。)

オプション

コマンド実行時のオプションを指定できます。

オプション説明
[-e(スクリプト)]スクリプトをコマンドに追加します。複数指定すれば、複数回のコマンドを実行できます。
[-E]拡張正規表現を利用する時に使用します。
[-f(ファイル名)]スクリプトが記述されているファイルを指定します。ファイルに記載されているコマンドを実行することが出来ます。
[-i]直接ファイルを編集します。
[-i(拡張子)]ファイルを直接編集して、指定した拡張子でバックアップを行います。
[-n]出力コマンドのみ出力します。
[-l (文字数)]lコマンドの出力行を折り返す長さを指定します。
[-r]拡張正規表現を利用する時に使用します。(Eと同じ)

アドレス

特定の行だけを処理したい場合は、コマンドの前に処理対象の位置を指定します。
これをアドレスといいます。アドレスは数字と「$」、正規表現が使用できます。
アドレスの後に「!」を付けると、アドレスで指定した意外という意味になります。

アドレス説明
[数字]行番号として認識されます。
[$]最終行として認識されます。
[/正規表現/]正規表現にマッチした行をコマンド処理します。
[開始行,終了行]開始行から終了行を指定できます。
[開始行˜数字]開始行から処理を開始して、数字で指定した間隔を処理の対象行とします。「10˜4」とした場合は10行目、14行目、18行目と4行間隔になります。
[アドレス,+数字]アドレスで指定した行の次から数字で指定した行を対象行として処理します。「/正規表現/,+4」正規表現にマッチする行から4行分が処理対象となります。

以下で簡単な使用例を紹介します。

文字列の置換

sedコマンドの最も一般的な使用法の一つは、文字列の置換です。次の例を参考にしてください。

sed 's/検索文字列/置換文字列/' ファイル名

このコマンドは、指定したファイル内の全てのインスタンスで検索文字列を置換文字列に置き換えます。

  1. 検索文字列: 置換したい文字列を指定します。
  2. 置換文字列: 検索文字列の代わりに挿入する文字列を指定します。

行の削除

sedコマンドを使用して特定の行を削除することもできます。以下の例をご覧ください。

sed '行番号d' ファイル名

このコマンドは、指定したファイル内の行番号で指定された行を削除します。

  1. 行番号: 削除したい行の番号を指定します。行番号は1から始まります。

行の追加

新しい行を既存のテキストに追加するには、sedコマンドのaコマンドを使用します。以下の例を参考にしてください。

sed '行番号a\追加するテキスト' ファイル名

このコマンドは、指定した行番号の直前に追加するテキストを挿入します。

  1. 行番号: 追加したい位置の直前の行番号を指定します。
  2. 追加するテキスト: 挿入したい新しい行の内容を指定します。

応用例

# 1: ファイル内の特定の文字列を置換する
sed 's/検索文字列/置換文字列/g' ファイル名
# ファイル内の全てのインスタンスで検索文字列を置換文字列に置き換えます。gフラグは、1行内の全てのマッチを置換するために使用されます。


# 2: 複数のスクリプトを組み合わせて処理を行う
sed -e 'スクリプト1' -e 'スクリプト2' ファイル名
# 複数のスクリプトを連結するために、-eオプションを使用します。これにより、複数の操作を順番に実行することができます。例えば、行の削除と置換を組み合わせることができます。

# 3: マッチする行のみを表示する
sed -n '/パターン/p' ファイル名
# -nオプションを使用すると、パターンにマッチする行のみが表示されます。この例では、指定したパターンにマッチする行のみが出力されます。

# 4: 行番号を付与する
sed = ファイル名 | sed 'N;s/\n/ /'
# ファイルの各行の前に行番号を付与します。最初のsedコマンドで行番号を追加し、2つ目のsedコマンドで行番号とテキストの間の改行をスペースに置換します。

これらは一部の応用例であり、sedコマンドは非常に柔軟なテキスト処理ツールです。他にもさまざまな操作が可能であり、正規表現や制御構造を組み合わせることで、さらに高度な編集が可能になります。sedコマンドのマニュアルやドキュメントも参考にしながら、様々な応用例を試してみてください。

awkコマンド

awkは入力として受け取った文字列に対して、フィールド区切り文字やレコード区切り文字を指定して、

「列」に対する処理を行うためのコマンドです。また、awk単体としても、1つのプログラムです。

以下にawkコマンドの基本的な構文を示します。

awk 'パターン {アクション}' ファイル名
  1. パターン: マッチングするための条件を指定します。行全体または特定のフィールドに対してパターンを指定できます。
  2. アクション: パターンにマッチした場合に実行するコードを指定します。フィールドの処理、条件分岐、出力のフォーマットなど、さまざまな操作が可能です。
  3. ファイル名: 処理を行いたいテキストファイルのパスを指定します。省略した場合は標準入力から読み込みます。

awkコマンドの基本的な使い方を理解したら、実際の使用例を実行してみましょう。

フィールドの操作

awkコマンドの強力な機能の一つは、フィールドの操作です。テキストの行は、デフォルトではスペースやタブでフィールドに分割されます。以下にいくつかのフィールド操作の例を示します。

  1. フィールドの出力: 特定のフィールドを出力するには、$記号を使用します。例えば、$1は最初のフィールド、$2は2番目のフィールドを表します。
  2. フィールドの編集: フィールド内の文字列の置換や操作を行うこともできます。正規表現や組み込み関数を使用してフィールドを編集できます。

パターンとアクションの組み合わせ

awkコマンドでは、パターンとアクションを組み合わせることでより柔軟な処理を実現できます。以下にいくつかの例を示します。

特定のパターンにマッチする行を表示する

awk '/パターン/ {print}' ファイル名

この例では、指定したパターンにマッチする行を表示します。printコマンドは、マッチする行全体を表示するために使用されます。

  1. パターン: マッチングするための正規表現パターンを指定します。
出力のカスタマイズ
awk '{printf "フィールド1: %s, フィールド2: %s\n", $1, $2}' ファイル名

この例では、各行のフィールド1とフィールド2をカスタムフォーマットで出力します。printf関数を使用して、出力の形式を指定します。

フィールドの合計や平均の計算

この例では、各行の最初のフィールドの合計値を計算し、最後に合計を表示します。sumという変数を使用して合計値を計算し、ENDパターンで最終的な合計を出力します。

これらは一部の応用例であり、awkコマンドは非常に柔軟なテキスト処理とデータ抽出のツールです。他にも様々な操作が可能であり、条件分岐、ループ、データの集計など、さまざまな応用があります。awkコマンドのマニュアルやドキュメントも参考にしながら、さまざまな応用例を試してみてください。

grepコマンド

grep は、 FILE で名前を指定された入力ファイル (ファイルが指定されてないか、 file の部分に – が指定された場合は標準入力) を読み込み、与えられた PATTERN にマッチする部分を含む行を探します。 デフォルト動作では、 grep はマッチした行を表示します。

さらに、2 つのプログラム egrep と fgrep を利用可能です。 egrep は grep-E と同じです。 fgrep は grep-F と同じです。 zgrep は grep-Z と同じです。

grep [オプション] 検索文字列 対象ファイル

よく利用するオプション

実際によく利用しているオプションについて記載します。  
これらを使いこなせれば一通りの検索はできるかなと思います。

オプション

オプション 説明
-E 拡張正規表現(ERE)を利用する
※このオプションなしでも正規表現の「. * ^ $ [ ]」は利用可能
-e [検索文字列] オプションの引数として検索文字列を指定する
このオプションを複数回使用することでOR検索が可能
-v 結果を反転する。検索文字列を含む行以外を表示 
-i 検索文字列の大文字と小文字を区別しない
-c マッチした行ではなく、マッチした行数を表示
-m [数字] [数字]行分だけ表示する
-B [数字]マッチした行の前 [数字] 行を表示
-A [数字]マッチした行の後 [数字] 行を表示
-C [数字]マッチした行の前後 [数字] 行を表示
-h 出力する行の前にファイル名を付けないようにする
-n 頭にそのファイル内での行数を表示

grepコマンドはLinuxを利用するにあたって必須ともいえるコマンドです。
使いこなせるようになればファイルの検索などのスピードが劇的にアップします。

sed・awk・grepを組み合わせて使用

これらのコマンドを組み合わせる事で、通常必要になる全ての文字列操作が可能になります。是非使い熟してください。

ファイル内の特定のパターンを検索して置換する

grep '検索パターン' ファイル名 | sed 's/置換文字列/新しい文字列/g'

この例では、grepコマンドを使用してファイル内の特定のパターンにマッチする行を検索し、sedコマンドを使用して置換操作を行います。マッチした行に含まれる置換文字列を新しい文字列に置換します。

特定の条件を満たす行を抽出する

awk '/パターン/ {print}' ファイル名 | grep '追加パターン'

この例では、awkコマンドを使用して特定のパターンにマッチする行を抽出し、その結果をgrepコマンドでさらに絞り込みます。最初にawkコマンドでパターンにマッチする行を抽出し、その結果をgrepコマンドでさらに特定のパターンでフィルタリングします。

特定のフィールドの値を抽出する

awk '{print $2}' ファイル名 | grep '検索パターン'

この例では、awkコマンドを使用してファイル内の各行の2番目のフィールドの値を抽出し、grepコマンドを使用して特定のパターンにマッチする値を検索します。ファイル内の各行から2番目のフィールドの値を抽出し、その結果をgrepコマンドで特定のパターンで検索します。

これらの実用例は、sedコマンドとawkコマンドをgrepコマンドと組み合わせて使用する場合の一部です。これらのコマンドを組み合わせることで、柔軟なテキスト処理やデータ抽出を実現できます。

正規表現

正規表現の基礎から応用までを徹底解説し、文字指定、文字数指定、位置指定などの様々なパーツを詳しく解説します。さらに、sedコマンドやawkコマンドで正規表現を使用した実例も紹介します。

正規表現の基本

正規表現は、テキストパターンのマッチングや検索に使用されるパターンです。以下に正規表現の基本要素を紹介します。

文字指定

  1. 一文字の指定: abcabcのいずれかの文字とマッチします。
  2. 文字範囲の指定: [a-z]はアルファベットの小文字とマッチします。[0-9]は数字とマッチします。
正規表現意味
A 1 aなど具体文字を指定
.何らかの1文字
[AHZ]どれかの文字に一致する
[0-9] \d何らかの半角数字
[a-z]何らかの小文字の半角英字
[A-Z]何らかの大文字の半角英字
[0-9a-zA-Z] \w何らかの半角英数字
\s改行文字を含んだ空白文字

文字数指定

  1. 任意の回数の指定: *は直前の文字が0回以上繰り返すことを意味します。例えば、ab*cacabcabbcなどとマッチします。
  2. 1回以上の指定: +は直前の文字が1回以上繰り返すことを意味します。例えば、ab+cabcabbcabbbcなどとマッチします。
  3. 固定回数の指定: {n}は直前の文字がちょうどn回繰り返すことを意味します。例えば、a{3}aaaとマッチします。
正規表現意味
*0回以上の繰り返し
+1回以上の繰り返し
?0回または1回の繰り返し
{1,3}1〜3回の繰り返し
{3,}3回以上の繰り返し
{,8}8回以内の繰り返し
{6}6回ちょうどの繰り返し

位置指定

  1. 行の先頭を指定: ^は行の先頭を意味します。^abcは行の先頭にabcがある場合にマッチします。
  2. 行の末尾を指定: $は行の末尾を意味します。abc$は行の末尾がabcで終わる場合にマッチします。
正規表現意味
^行頭を表す
$行末を表す

sedコマンドでの正規表現の使用例

文字列の置換

sed 's/正規表現/置換文字列/g' ファイル名

この例では、指定した正規表現にマッチする文字列を置換文字列で置き換えます。gフラグは、1行内の全てのマッチを置換するために使用されます。

行の削除

sed '/正規表現/d' ファイル名

この例では、指定した正規表現にマッチする行を削除します。dコマンドは、マッチする行を削除するために使用されます。

パターンの抽出

sed -n '/正規表現/p' ファイル名

この例では、指定した正規表現にマッチする行を抽出して表示します。-nオプションは、デフォルトの出力を抑制し、マッチする行だけを表示するために使用されます。

awkコマンドでの正規表現の使用例

特定のパターンにマッチする行の表示

awk '/正規表現/ {print}' ファイル名

この例では、指定した正規表現にマッチする行を表示します。printコマンドはマッチした行を表示するために使用されます。

特定のフィールドの抽出

awk '{print $2}' ファイル名 | grep '正規表現'

この例では、ファイル内の各行の2番目のフィールドの値を抽出し、grepコマンドで特定の正規表現にマッチする値を検索します。$2は2番目のフィールドを意味し、printコマンドによってフィールドの値が表示されます。

これらの例は、sedコマンドとawkコマンドで正規表現を使用する一部の実例です。正規表現は非常に強力なパターンマッチングツールであり、テキスト処理やデータ抽出において重要な役割を果たします。

sedとawkの違い

sed と awk の主な違いは、sed は検索やフィルタリング、テキスト処理のために文字のストリームを扱うコマンドユーティリティであり、一方 awk は if/else, while, do/while などの高度なプログラミング構造を持つ sed よりも強力で堅牢であるということです。

私個人の使い分けは、sed は、あくまで行単位が処理ベースになりますので、それより、複雑な処理は、awkになる位に使い分けています。

Linuxを触るなら、特に「sedコマンド」は必須だと思いますので、まず「sedコマンド」を使いこなせるようになって下さい。

まとめ

文字列操作コマンド(sed/awk/grep)アドレス、コマンド、オプションと覚えることは複数あり大変ですが、テキストファイルの編集作業をやる時は手作業で1ファイルずつやるより、文字列操作コマンドを使用した方が正確性が上がるので、是非身につけて下さい。
他のコマンドと組み合わせることで、テキストファイルの編集、指定したキーでのソート、ファイルの結合などができるようになります。
これらの一連のコマンドをシェルスクリプトにすれば、さらに利便性が上がると思います。
手作業でファイル編集をやるには、少し大変だと思った時は積極的にこれらのコマンドを利用する事で、すぐに使いこなせるようになります。