複数行のGensub

複数行のGensub

次のようなランダムな行を持つファイルがあります。

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行にgensub1回実行します。実際に欲しいことができますが、awk実際にはその作業に最適なツールではありません。

私が知っている限り、あなたは大きなファイルを持っていて、次の数字mark:とスペースだけを印刷したいと思います。もしそうなら、これらすべての方法があなたの周りにとどまるよりも簡単ですgensub

  1. grepPerl準拠の正規表現と共に使用されます(-P

    $ grep -oP 'mark:\s*\K\d+' file 
    98
    

    -o製造元はgrepライン上の一致部分のみを印刷します。これは\K、「このポイントの前に一致するすべてのエントリを無視します」を意味するPCRE構成です。

  2. sed

    $ sed -n 's/.*mark:\s*\([0-9]\+\).*/\1/p' file
    98
    

    正常な出力を抑制します-n。交換が成功した場合にのみp最後に印刷されます。sed正規表現自体は、次の数値文字列mark:とゼロ個以上の空白文字をキャプチャし、行全体をキャプチャされたコンテンツに置き換えます。

  3. 真珠

    $ perl -ne 'print if s/.*mark:\s*(\d+).*/$1/' file
    98
    

    -nPerlに入力ファイルを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内容全体をすぐに読みます。

おすすめ記事