Awkコマンドがある場合
pattern { ... }
パターンはキャプチャグループを使用していますが、ブロックでキャプチャされた文字列にアクセスするにはどうすればよいですか?
それは散歩の思い出のレーンだった...
ずっと前にawkをPerlに置き換えました。
どうやらAWK正規表現エンジンはそのグループをキャプチャしません。
あなたは次のようなものを使用することを検討するかもしれません:
Perl -n -e'/test(\d+)/ && print $1'
-nフラグにより、Perlはawkのようにすべての行をループします。
Gawkでは、match
関数を使用して、括弧で囲まれたグループをキャプチャできます。
gawk 'match($0, pattern, ary) {print ary[1]}'
例:
echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}'
cd
を出力します。
問題の機能を実装するgawkの特定の使用に注意してください。
移植可能な代替手段として、match()
およびsubstr
を使用して同様の結果を達成できます。
例:
echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'
cd
を出力します。
これは常に必要なものなので、bash関数を作成しました。それはグレンジャックマンの答えに基づいています。
これを.bash_profileなどに追加します。
function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }
ファイル内の各行の正規表現をキャプチャする
$ cat filename | regex '.*'
ファイル内の各行の最初の正規表現キャプチャグループをキャプチャする
$ cat filename | regex '(.*)' 1
GNU awkを使用できます。
$ cat hta
RewriteCond %{HTTP_Host} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]
$ gawk 'match($0, /.*(http.*?)\$/, m) { print m[1]; }' < hta
http://www.mysite.net/
拡張機能なしで、Vanilla awkでのキャプチャもシミュレートできます。ただし、直感的ではありません:
手順1. gensubを使用して、文字列に表示されない文字で一致を囲みます。ステップ2.キャラクターに対してsplitを使用します。手順3.分割された配列内の他のすべての要素がキャプチャグループです。
$ echo 'ab cb ad' | awk '{split(gensub(/ a ./、SUBSEP "&" SUBSEP、 "g"、$ 0)、cap、SUBSEP);印刷キャップ[2] "|" cap [4]; } ' ab | ad
Peter Tillemansの答えをラップするbash関数を思い付くのに少し苦労しましたが、ここに私が思いついたものがあります:
関数正規表現{Perl -n -e "/ $ 1/&& printf \"%s\n\"、" '$ 1'}
「ms」を出力したくないので、次の正規表現引数については、これはopsbのawkベースのbash関数よりも優れていることがわかりました。
'([0-9]*)ms$'