awkで複数の区切り文字を使用する


202

次の行を含むファイルがあります。

/logs/tc0001/tomcat/tomcat7.1/conf/catalina.properties:app.env.server.name = demo.example.com
/logs/tc0001/tomcat/tomcat7.2/conf/catalina.properties:app.env.server.name = quest.example.com
/logs/tc0001/tomcat/tomcat7.5/conf/catalina.properties:app.env.server.name = www.example.com

上記の出力では、3つのフィールド(2、4、最後のフィールド)を抽出します*.example.com。次の出力が表示されます。

cat file | awk -F'/' '{print $3 "\t" $5}'
tc0001   tomcat7.1
tc0001   tomcat7.2
tc0001   tomcat7.5

最後のフィールドを後のドメイン名で抽出するにはどうすればよい'='ですか?multiple delimiterフィールドを抽出するにはどうすればよいですか?


2
同じですが異なる私の質問に答えるためにawk、フィールドが空白のときにフィールドを飲み込んで、フィールドの番号付けを妨害しました。空のフィールドに変更-F " "-F "[ ]"awk飲み込みませんでした。
アダム

回答:


324

区切り文字には正規表現を使用できます。

awk -F'[/=]' '{print $3 "\t" $5 "\t" $8}' file

生成する:

tc0001   tomcat7.1    demo.example.com  
tc0001   tomcat7.2    quest.example.com  
tc0001   tomcat7.5    www.example.com

42
もちろん、catプロセスは必要ありませんawk '...' file。また、それは出力フィールドセパレータを使用するように整然と次のようになりますawk -F'[/=]' -v OFS="\t" '{print $3, $5, $8}'
グレンはジャックマン

17
awk区切り文字は正規表現にすることができます...これで私の1日が終わりました!
das.cyklone 2014

4
@ das.cyklone:awkには複数の区切り文字を含めることもできます|:ex:(awk -F 'this|that|[=/]' '......' 単語/文字列で区切ります)(これにより、2つの区切り文字の間のフィールドにスペースが保持されることに注意してください。追加|[ \t]+すると便利な場合もありますが、トリッキー...「this」の前後にスペースがあることが多いため、スペースと「this」の間に2つの追加の空のフィールドが表示されます)
Olivier Dulac

私はこれを2つの異なるディストリビューションで試しましたが、同じ動作が得られます。netstat-ntpl "netstat -ntpl | sed 's /:/ /' | awk '{print $ 5}'"からポートを取得したいのですが、これは機能しますが、フィールド17のデータは予期していませんでした: "netstat -ntpl | awk -F" |: "'{print $ 17}'"
louigi600

2
はい...これは私が欲しかったものを得ました:awk -F "[:] +" '/ \ / postmaster * $ / {print $ 5}'
louigi600

44

朗報!awkフィールド区切り文字は正規表現にすることができます。あなただけを使用する必要があります-F"<separator1>|<separator2>|..."

awk -F"/|=" -vOFS='\t' '{print $3, $5, $NF}' file

戻り値:

tc0001  tomcat7.1  demo.example.com
tc0001  tomcat7.2  quest.example.com
tc0001  tomcat7.5  www.example.com

ここに:

  • -F"/|="入力フィールド区切り文字を/またはに設定します=。次に、出力フィールド区切り文字をタブに設定します。

  • -vOFS='\t'-v変数を設定するためにフラグを使用しています。OFS出力フィールドセパレータのデフォルト変数であり、タブ文字に設定されています。のようなOFSの組み込みがないため、フラグが必要-Fです。

  • {print $3, $5, $NF} 入力フィールドセパレータに基づいて、3番目、5番目、最後のフィールドを印刷します。


別の例を参照してください:

$ cat file
hello#how_are_you
i#am_very#well_thank#you

このファイルには、2つのフィールド区切り文字、#およびがあり_ます。セパレーターがどちらであるかに関係なく2番目のフィールドを印刷したい場合は、両方をセパレーターにしましょう!

$ awk -F"#|_" '{print $2}' file
how
am

ファイルの番号は次のとおりです。

hello#how_are_you           i#am_very#well_thank#you
^^^^^ ^^^ ^^^ ^^^           ^ ^^ ^^^^ ^^^^ ^^^^^ ^^^
  1    2   3   4            1  2   3    4    5    6

1
編集をありがとう@BUFU OFSのリファレンスを削除してFSの部分だけに焦点を当てましたが、それも持っていることは良いことです。乾杯!
fedorqui 'SO stop harming'

5

空白が一貫している場合は、それを区切り文字として使用できます。また\t、直接挿入する代わりに、出力区切り記号を設定すると、自動的に挿入されます。

< file awk -v OFS='\t' -v FS='[/ ]' '{print $3, $5, $NF}'

3

数字25または文字a#またはスペースのフィールドセパレータの場合、区切り文字は2回以上6回以下繰り返す必要があります。次に例を示します。

awk -F'[2-5a# ]{2,6}' ...

()とパラメーターを使用して、これのバリエーションが存在することを確信しています


3

Perlワンライナー:

perl -F'/[\/=]/' -lane 'print "$F[2]\t$F[4]\t$F[7]"' file

次のコマンドラインオプションが使用されます。

  • -n入力ファイルのすべての行をループし、その行を$_変数に入れ、すべての行を自動的に印刷しない

  • -l 処理前に改行を削除し、後で追加します

  • -aautosplitモード– perlは自動的に入力行を@F配列に分割します。デフォルトでは空白での分割

  • -Fautosplit修飾子。この例では、/または=

  • -e Perlコードを実行する

Perlはawkと密接に関連してい@Fますが、autosplit配列はインデックスから始まり、$F[0]awkフィールドは$ 1から始まります。


2

もう1つは-Fオプションを使用するが、正規表現を渡してテキストを左括弧と右括弧の間に出力する方法()です。

ファイルの内容:

528(smbw)
529(smbt)
530(smbn)
10115(smbs)

コマンド:

awk -F"[()]" '{print $2}' filename

結果:

smbw
smbt
smbn
smbs

awkを使用して、次のテキストを印刷します[]

使用awk -F'[][]' が、 awk -F'[[]]'動作しません。

http://stanlo45.blogspot.com/2020/06/awk-multiple-field-separators.html


自分のブログにリンクしている評判が1のユーザーは通常10名のうち9名がスパムであるので、あなたの回答は削除キューに入れられました。しかし、あなたのものはルールの例外です。過去10年間のコンテンツには金鉱があります。うまくいけば、それを不滅にする計画があります。
Eric Leschinski

0

完璧な答えがたくさん出てきているようですが、私のコードもアップロードしたいと思います。

awk -F"/" '{print $3 " " $5 " " $7}' sam | sed 's/ cat.* =//g'


2
print $3 " " $5 " " $7と同じように印刷できますprint $3, $5, $7。また、awkを使用してsedにパイピングする利点はわかりません。一般に、awkは十分であり、他の回答はそれを示しています。
fedorqui「SO害をやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.