次のようなランダムな行を持つファイルがあります。
aaa bbb
ccc ddd
eee mark: 98 fff
ggg ggg jjjj iii
jjj kkkk
awkとgensubだけを使って上記の数字「98」を一致させたい。これまでに以下のコードがありますが、gensubに "\ n"を別の文字として扱わせる必要があるため、うまくいかないようです。
cat file.txt | awk 'printf(gensub(/^.*mark: ([0-9]+).*$/,"\\1","g"))}'
上記のコードの出力は「98」のみ必要です。どうすればいいですか?
編集する
sまたはm修飾子を使用しても、私が知っている限り、「s」修飾子は正規表現を処理する必要があるため機能しません。 \n を含むすべての文字で。
ベストアンサー1
awk
入力が複数行の文字列として扱われると思います。しかし、実際にはそうではありません。ファイルから awk スクリプトを実行すると、そのスクリプトが適用されます。ファイルの各行にそれぞれ。したがって、1行にgensub
1回実行します。実際に欲しいことができますが、awk
実際にはその作業に最適なツールではありません。
私が知っている限り、あなたは大きなファイルを持っていて、次の数字mark:
とスペースだけを印刷したいと思います。もしそうなら、これらすべての方法があなたの周りにとどまるよりも簡単ですgensub
。
grep
Perl準拠の正規表現と共に使用されます(-P
)$ grep -oP 'mark:\s*\K\d+' file 98
-o
製造元はgrep
ライン上の一致部分のみを印刷します。これは\K
、「このポイントの前に一致するすべてのエントリを無視します」を意味するPCRE構成です。sed
$ sed -n 's/.*mark:\s*\([0-9]\+\).*/\1/p' file 98
正常な出力を抑制します
-n
。交換が成功した場合にのみp
最後に印刷されます。sed
正規表現自体は、次の数値文字列mark:
とゼロ個以上の空白文字をキャプチャし、行全体をキャプチャされたコンテンツに置き換えます。真珠
$ perl -ne 'print if s/.*mark:\s*(\d+).*/$1/' file 98
-n
Perlに入力ファイルを1行ずつ読み、与えられたスクリプトを適用するように指示します-e
。スクリプトは、置換が成功したすべての行を印刷します。
本当に本当に使いたいなら、gensub
次のようにしてください。
$ awk '/mark:/{print gensub(/.*mark:\s*([0-9]+).*/,"\\1","g")}' file
98
個人的に私はawkでこれを行います。
$ awk '/mark:/{gsub(/[^0-9]/,"");print}' file
98
awkに複数行の入力を許可させたいと思うので、次のようにすることができます(ファイルにNULL文字がないと仮定)。
$ awk '{print(gensub(/^.*mark: ([0-9]+).*$/,"\\1","g"))}' RS='\0' file
98
RS='\0'
入力レコード区切り記号(つまり定義された「行」awk
)をに設定します\0
。ファイルにこれらの文字がないので、awk
内容全体をすぐに読みます。