LinuxでAWK言語を使用してテキストを操作する方法

提供:Dev Guides
移動先:案内検索

序章

Linuxユーティリティは、多くの場合、Unixの設計哲学に従います。 ツールは小さく、入力と出力にプレーンテキストファイルを使用し、モジュール方式で動作することをお勧めします。 このレガシーにより、sedawkなどのツールを使用した優れたテキスト処理機能があります。

awkは、非常に便利な方法でテキストデータを操作するために使用できるプログラミング言語とテキストプロセッサの両方です。 このガイドでは、awkコマンドラインツールの使用方法と、それを使用してテキストを処理する方法について説明します。

インタラクティブターミナルを起動します!

基本構文

awkコマンドは、すべての最新のLinuxシステムにデフォルトで含まれているため、使用を開始するためにインストールする必要はありません。

awkは、予測可能な方法でフォーマットされたテキストファイルを処理する場合に最も役立ちます。 たとえば、表形式のデータの解析と操作に優れています。 行ごとに動作し、ファイル全体を反復処理します。

デフォルトでは、フィールドを区切るために空白(スペース、タブなど)を使用します。 幸い、Linuxシステム上の多くの構成ファイルはこの形式を使用しています。

awkコマンドの基本的な形式は次のとおりです。

awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

awkコマンドでは、検索部分またはアクション部分のいずれかを省略できます。 デフォルトでは、「アクション」部分が指定されていない場合に実行されるアクションは「印刷」です。 これは、一致するすべての行を単に印刷します。

検索部分が指定されていない場合、awkは各行にリストされているアクションを実行します。

両方が指定されている場合、awkは検索部分を使用して、現在の行がパターンを反映しているかどうかを判断し、一致するアクションを実行します。

最も単純な形式では、catのようなawkを使用して、テキストファイルのすべての行を画面に出力できます。

友達のグループの好きな食べ物をリストしたfavorite_food.txtファイルを作成します。

echo "carrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica" > favorite_food.txt

次に、awkコマンドを使用して、ファイルを画面に出力します。

awk '{print}' favorite_food.txt

画面にファイルが印刷されます。

Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica

これはあまり役に立ちません。 ファイルを検索して「sand」というテキストを検索することにより、awkの検索フィルタリング機能を試してみましょう。

awk '/sand/' favorite_food.txt
Outputcarrot sandy
sandwich brian

ご覧のとおり、awkは、「砂」の文字が含まれている行のみを印刷するようになりました。

正規表現を使用すると、テキストの特定の部分をターゲットにすることができます。 「sand」の文字で始まる行のみを表示するには、正規表現^sandを使用します。

awk '/^sand/' favorite_food.txt

今回は、次の1行のみが表示されます。

Outputsandwich brian

同様に、アクションセクションを使用して、印刷する情報を指定できます。 たとえば、最初の列のみを印刷するには、次のコマンドを使用します。

awk '/^sand/ {print $1;}' favorite_food.txt
Outputsandwich

列番号に関連付けられた変数によって、(空白で区切られた)すべての列を参照できます。 たとえば、最初の列は$1、2番目の列は$2であり、$0で行全体を参照できます。

内部変数と拡張フォーマット

awkコマンドは、ファイルを処理するときに、いくつかの内部変数を使用して特定の情報を割り当てます。

awkが使用する内部変数は次のとおりです。

  • FILENAME :現在の入力ファイルを参照します。
  • FNR :現在の入力ファイルを基準にした現在のレコードの番号を参照します。 たとえば、入力ファイルが2つある場合、合計ではなく、各ファイルのレコード数がわかります。
  • FS :レコード内の各フィールドを示すために使用される現在のフィールドセパレータ。 デフォルトでは、これは空白に設定されています。
  • NF :現在のレコードのフィールド数。
  • NR :現在のレコードの番号。
  • OFS :出力データのフィールドセパレータ。 デフォルトでは、これは空白に設定されています。
  • ORS :出力データのレコードセパレータ。 デフォルトでは、これは改行文字です。
  • RS :入力ファイル内の個別のレコードを区別するために使用されるレコード区切り文字。 デフォルトでは、これは改行文字です。

これらの変数の値は、ファイルのニーズに合わせて自由に変更できます。 通常、これは処理の初期化フェーズで行います。

これは私たちに別の重要な概念をもたらします。 awk構文は、これまでに使用したものよりも少し複雑です。オプションのBEGINおよびENDブロックもあり、ファイル処理の前後に実行するコマンドを含めることができます。 、 それぞれ。

これにより、拡張構文は次のようになります。

awk 'BEGIN { action; }
/search/ { action; }
END { action; }' input_file

BEGINおよびENDキーワードは、検索パラメーターと同様に、特定の条件のセットです。 これらは、ドキュメントが処理される前後で一致します。

これは、BEGINセクションでいくつかの内部変数を変更できることを意味します。 たとえば、/etc/passwdファイルは、空白ではなくコロン(:)で区切られます。

このファイルの最初の列を印刷するには、次のコマンドを実行します。

awk 'BEGIN { FS=":"; }
{ print $1; }' /etc/passwd
Outputroot
daemon
bin
sys
sync
games
man
. . .

BEGINおよびENDブロックを使用して、印刷しているフィールドに関する情報を印刷できます。 次のコマンドを使用して、データをファイルからテーブルに変換し、\tを使用してタブの間隔を適切に設定します。

awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
{print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
END { print "---------\nFile Complete" }' /etc/passwd

次の出力が表示されます。

OutputUser        UID     GID     Home        Shell
--------------
root         0       0       /root       /bin/bash
daemon       1       1       /usr/sbin       /bin/sh
bin          2       2       /bin        /bin/sh
sys          3       3       /dev        /bin/sh
sync         4       65534       /bin        /bin/sync
. . .
---------
File Complete

ご覧のとおり、awkの機能のいくつかを利用することで、非常にうまくフォーマットできます。

展開された各セクションはオプションです。 実際、別のセクションが定義されている場合、メインアクションセクション自体はオプションです。 たとえば、次のようなことができます。

awk 'BEGIN { print "We can use awk like the echo command"; }'

そして、次の出力が表示されます。

OutputWe can use awk like the echo command

次に、出力のフィールド内でテキストを検索する方法を見てみましょう。

フィールド検索と複合式

前の例の1つでは、「sand」で始まるfavorite_food.txtファイルの行を印刷しました。 行全体の先頭を探していたので、これは簡単でした。

代わりにフィールドの先頭で検索パターンが一致したかどうかを知りたい場合はどうなりますか?

favorite_food.txtファイルの新しいバージョンを作成して、各人の食べ物の前にアイテム番号を追加します。

echo "1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
5 spaghetti jessica" > favorite_food.txt

このファイルから「sa」で始まるすべての食品を検索する場合は、次のようなものを試すことから始めることができます。

awk '/sa/' favorite_food.txt

これにより、「sa」を含むすべての行が表示されます。

Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan

ここでは、単語内の「sa」の任意のインスタンスに一致しています。 これには、中央にパターンがある「わさび」や、目的の列にない「砂」などが含まれることになります。 この場合、second列に「sa」が含まれるbeginningという単語にのみ関心があります。

次のコマンドを使用して、awkに2番目の列の先頭でのみ一致するように指示できます。

awk '$2 ~ /^sa/' favorite_food.txt

ご覧のとおり、これにより、2番目の列の先頭でのみ一致するものを検索できます。

field_num ~の部分は、awkが2番目の列にのみ注意を払う必要があることを指定しています。

Output3 sandwich brian
4 salad ryan

「!」を含めることで、一致しないものを簡単に検索できます。 チルダの前の文字(〜)。 このコマンドは、「sa」で始まる食べ物がないすべての行を返します。

awk '$2 !~ /^sa/' favorite_food.txt
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica

後で「sa」で始まらない行のみに関心があり、アイテム番号が5未満であると判断した場合は、次のような複合式を使用できます。

awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

これにより、いくつかの新しい概念が導入されます。 1つ目は、&&演算子を使用して、一致する回線の要件を追加する機能です。 これを使用して、ラインが一致するように任意の数の条件を組み合わせることができます。 この場合、この演算子を使用して、最初の列の値が5未満であることを確認するチェックを追加しています。

次の出力が表示されます。

Output1 carrot sandy
2 wasabi luke

awkを使用してファイルを処理できますが、他のプログラムの出力を操作することもできます。

他のプログラムからの出力の処理

ファイル名を指定する代わりに、awkコマンドを使用して、他のプログラムの出力を解析できます。 たとえば、awkを使用して、ipコマンドからIPv4アドレスを解析できます。

ip aコマンドは、IPアドレス、ブロードキャストアドレス、およびマシン上のすべてのネットワークインターフェイスに関するその他の情報を表示します。 eth0というインターフェイスの情報を表示するには、次のコマンドを使用します。

ip a s eth0 

次の結果が表示されます。

Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

awkを使用してinet行をターゲットにしてから、IPアドレスだけを出力できます。

ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

-Fフラグは、正規表現[\/ ]+を使用して、スラッシュまたはスペースで区切るようにawkに指示します。 これにより、行 inet 172.17.0.11/16が別々のフィールドに分割されます。 スペースとスラッシュで区切っているため、行の先頭のスペースもフィールドとしてカウントされるため、IPアドレスは3番目のフィールドにあります。 この場合、awkは連続するスペースを単一のスペースとして扱うことに注意してください。

出力にはIPアドレスが表示されます。

Output172.17.0.11

awkを使用して他のコマンドの出力を検索または解析できる場所はたくさんあります。

結論

これで、awkコマンドを使用して、テキストファイルとテキストストリームを操作、フォーマット、および選択的に印刷する方法の基本を理解できたはずです。 ただし、Awkははるかに大きなトピックであり、実際には、変数の割り当て、制御構造、組み込み関数などを備えたプログラミング言語全体です。 独自のスクリプト内で使用して、信頼できる方法でテキストをフォーマットできます。

awkの詳細については、その作成者による無料のパブリックドメインの本を読むことができます。