たとえば、次の文字列があります。
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]
MATCH
検索を使用して値10を印刷したいですawk
。従来の方法を使用してこれを行うことはできますが、またはを使用してgrep
方法cut
を探したいと思います。sed
awk
MATCH
行はどこにでもあります。
答え1
sed -n 's/.* MATCH: \([^ ]*\).*/\1/p'
" MATCH: "
一致する各行の右端にある空白以外の文字シーケンスを印刷します。
-n
sed
デフォルトでは印刷されないパターンスペースを指定します。置換が成功すると、コマンドp
のフラグはパターン空間(つまり代替結果)をs
印刷するように指示します。sed
だから:
sed -n 's/pattern/replacement/p'
正常な代替結果を印刷する一般的な慣用語です。
上記は、入力が有効なテキストであると仮定しています。なぜなら、.*
どのシーケンスとも一致するからです。数値、有効な文字を形成しないバイトシーケンスと一致しません。これは通常、テキストが別のエンコーディングで処理されるときにUTF-8ロケールで発生します。このような状況が発生した場合は、上記の行の前に追加してくださいLC_ALL=C
。これにより、sed
各バイトが文字として扱われるため、誤ったバイトシーケンスが発生する可能性はありません。ここでは、一致する文字がすべてポータブル文字セットに属するため、機能します。
標準には、その機能がawk
キャプチャグループ(キャプチャイン)をサポートしていないため、対応する項目はありません。\(...\)
\1
sub()
ここでは、次の機能を使用する必要がありますmatch()
。
awk 'match($0, / MATCH: [^ ]*/) {
print substr($0, RSTART+8, RLENGTH-8)}'
または、次の技術を使用してください。
awk -F ' MATCH: ' 'NF>1 {sub(/ .*/, "", $2); print $2}'
(考える方は参考にしてください。一番左起こった" MATCH: "
)。
GNUには、コマンドと同様の機能がありますawk
が、置き換えが行われたかどうかを知らせないという設計バグがあります。ここでは、次のことができます。gensub()
sed
s
gawk '(replacement = gensub(/.* MATCH: ([^ ]*).*/, "\\1", 1)) != $0 {
print replacement}'
答え2
すべての行の形式が同じであると仮定すると(または少なくとも含まれるすべての行MATCH:
)、行の5番目の要素のように見え、MATCH:
必要な値は6番目の要素です。
したがって、awkは5番目の要素が同じかどうかをテストし、MATCH:
そうであればその行の6番目の要素を印刷します。
$ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ if ($5 == "MATCH:") print $6 }'
10
編集:仮説が行の任意MATCH:
の場所にある可能性があることを考慮すると、次のようになります。
$ echo "2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]" |awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}'
10
非常にエレガントではないかもしれませんが、行のすべてのフィールドを繰り返し、各フィールドをテストする必要があります。これはループfor
とテストでif
行われます。テストフィールドが一致すると、次のフィールドが印刷されます。
次の行に直接移動し、現在のフィールドの繰り返しを続行するために中断を追加しました。
複数行ファイルの場合:
$ cat terst
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 10 [text]
2017-01-19:31:51 [ABCD:] 37723 - MATCH: 11 [text]
2017-01-19:31:51 [ABCD:] 37723 - [text]
2017-01-19:31:51 37723 - MATCH: 12 [text]
$ awk -e '{ for (x=1; x<NF; x++ ) { if ($x == "MATCH:") {x=x+1; printf("%s\n", $x); break}}}' terst
10
11
12