LinuxでAWK言語を使用してテキストを操作する方法
序章
Linuxユーティリティは、多くの場合、Unixの設計哲学に従います。 ツールは小さく、入力と出力にプレーンテキストファイルを使用し、モジュール方式で動作することをお勧めします。 このレガシーにより、sedや awk
.
awk
はプログラミング言語であり、テキストデータを非常に便利な方法で操作するために使用できるテキストプロセッサです。 このガイドでは、 awk
コマンドラインツールとそれを使用してテキストを処理する方法。
基本構文
The awk
コマンドは、最近のすべてのLinuxシステムにデフォルトで含まれているため、使用を開始するためにインストールする必要はありません。
awk
予測可能な方法でフォーマットされたテキストファイルを処理する場合に最も役立ちます。 たとえば、表形式のデータの解析と操作に優れています。 行ごとに動作し、ファイル全体を反復処理します。
デフォルトでは、フィールドを区切るために空白(スペース、タブなど)を使用します。 幸い、Linuxシステム上の多くの構成ファイルはこの形式を使用しています。
の基本的な形式 awk
コマンドは次のとおりです。
- awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse
検索部分またはアクション部分のいずれかを任意の部分から省略できます awk
指図。 デフォルトでは、「アクション」部分が指定されていない場合に実行されるアクションは「印刷」です。 これは、一致するすべての行を単に印刷します。
検索部分が指定されていない場合、 awk
各行にリストされているアクションを実行します。
両方が与えられた場合、 awk
検索部分を使用して、現在の行がパターンを反映しているかどうかを判断し、一致に対してアクションを実行します。
最も単純な形式では、次を使用できます awk
お気に入り cat
テキストファイルのすべての行を画面に出力します。
作成する 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
これはあまり役に立ちません。 やってみよう awk
ファイルを検索して「sand」というテキストを検索することによる、の検索フィルタリング機能:
- awk '/sand/' favorite_food.txt
Outputcarrot sandy
sandwich brian
ご覧のように、 awk
「砂」の文字が含まれている行のみを印刷するようになりました。
正規表現を使用すると、テキストの特定の部分をターゲットにすることができます。 「砂」の文字で始まる行のみを表示するには、正規表現を使用します ^sand
:
- awk '/^sand/' favorite_food.txt
今回は、次の1行のみが表示されます。
Outputsandwich brian
同様に、アクションセクションを使用して、印刷する情報を指定できます。 たとえば、最初の列のみを印刷するには、次のコマンドを使用します。
- awk '/^sand/ {print $1;}' favorite_food.txt
Outputsandwich
列番号に関連付けられた変数によって、(空白で区切られた)すべての列を参照できます。 たとえば、最初の列は $1
、2番目は $2
、および行全体を参照できます $0
.
内部変数と拡張フォーマット
The awk
コマンドは、ファイルを処理するときに、いくつかの内部変数を使用して特定の情報を割り当てます。
内部変数 awk
用途は次のとおりです。
- FILENAME :現在の入力ファイルを参照します。
- FNR :現在の入力ファイルを基準にした現在のレコードの番号を参照します。 たとえば、入力ファイルが2つある場合、合計ではなく、各ファイルのレコード数がわかります。
- FS :レコード内の各フィールドを示すために使用される現在のフィールドセパレータ。 デフォルトでは、これは空白に設定されています。
- NF :現在のレコードのフィールド数。
- NR :現在のレコードの番号。
- OFS :出力データのフィールドセパレータ。 デフォルトでは、これは空白に設定されています。
- ORS :出力データのレコードセパレータ。 デフォルトでは、これは改行文字です。
- RS :入力ファイル内の個別のレコードを区別するために使用されるレコード区切り文字。 デフォルトでは、これは改行文字です。
これらの変数の値は、ファイルのニーズに合わせて自由に変更できます。 通常、これは処理の初期化フェーズで行います。
これは私たちに別の重要な概念をもたらします。 The awk
構文は、これまでに使用したものよりも少し複雑です。オプションもあります BEGIN
と END
ファイル処理の前後にそれぞれ実行するコマンドを含むことができるブロック。
これにより、拡張構文は次のようになります。
- awk 'BEGIN { action; }
- /search/ { action; }
- END { action; }' input_file
The 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つでは、次の行を印刷しました。 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番目の列の先頭でのみ一致するものを検索できます。
The 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
からIPv4アドレスを解析します ip
指図。
The 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}'
The -F
フラグが伝えます awk
正規表現を使用してスラッシュまたはスペースで区切る [\/ ]+
. これは行を分割します inet 172.17.0.11/16
別のフィールドに。 スペースとスラッシュで区切っているため、行の先頭のスペースもフィールドとしてカウントされるため、IPアドレスは3番目のフィールドにあります。 ご了承ください awk
この場合、連続するスペースは単一のスペースとして扱われます。
出力にはIPアドレスが表示されます。
Output172.17.0.11
あなたが使用できる多くの場所を見つけるでしょう awk
他のコマンドの出力を検索または解析します。
結論
これで、使用方法の基本を理解できたはずです。 awk
テキストファイルとテキストストリームを操作、フォーマット、および選択的に印刷するコマンド。 ただし、Awkははるかに大きなトピックであり、実際には、変数の割り当て、制御構造、組み込み関数などを備えたプログラミング言語全体です。 独自のスクリプト内で使用して、信頼できる方法でテキストをフォーマットできます。
詳細については awk
、あなたはその作成者による無料のパブリックドメインの本を読むことができます。