このデータで判断すると:
"STRING1","c45621396a774a7a79b095a1b73b1d3b","2016-04-14T19:39:41.529978","1.0.4.4","7-sp1.0-amd64","","10.224.241.219|0.0.0.0|0.0.0.0|192.168.0.6|0.0.0.0"
"STRING2","c5815139f3051de2ab67909b03a01203","2016-04-14T19:37:47.991569","1.0.4.4","7-sp1.0-amd64","","10.230.16.188"
"STRING3","c837513923e2abfe4df41c2240d1c869","2016-04-14T19:40:10.385759","1.0.4.4","7-sp1.0-amd64","","0.0.0.0|0.0.0.0|0.0.0.0|10.226.41.43"
"STRING4","c837544923e2abfe4df41c2240d1c869","2016-04-14T19:40:10.385779","1.0.4.4","7-sp0.0-amd64","","8.8.8.8|0.0.0.0|0.0.0.0|0.0.0.0|10.226.41.43"
"STRING5","c837544003e2abfe4df41c2240d1c869","2016-04-14T19:40:10.382379","1.0.4.4","7-sp0.0-amd64","","0.0.0.0|10.20.40.6|0.0.0.0|10.226.41.43"
私はただ大事にしたい
- 最初のフィールド(予測不可能な英数字/長さの文字列)と
- 6番目のフィールドから10で始まるIPアドレスのみがあります(1つ以上の可能性があります)。
以下の例によると、望ましい出力は次のようになります。
STRING1 10.224.241.219
STRING2 10.230.16.188
STRING3 10.226.41.43
STRING4 10.226.41.43
STRING5 10.20.40.6 10.226.41.43
これを達成するために、sed / awkにはどのような魔法がありますか? GNU / Linuxシステムまたはcygwinの標準テキスト処理ユーティリティを使用してこれを達成できます。
ありがとう
答え1
フィールドにカンマが含まれていない場合は、次のことを試すことができます。
$ perl -F, -lane '@k=split(/["|]/,$F[6]);
@l=grep{/^10\./}@k;
print "$F[0] @l"' file |
sed 's/"//g'
STRING1 10.224.241.219
STRING2 10.230.16.188
STRING3 10.226.41.43
STRING4 10.226.41.43
STRING5 10.20.40.6 10.226.41.43
説明する
-a
Perlにはこのように動作させるオプションがありますawk
。 Perlは与えられた値に基づいて入力ファイルを分割し、-F
各結果フィールドを配列の要素として保存します@F
。したがって、最初のフィールドは$F[0]
、2番目のフィールド$F[1]
は等になります。このオプションは、-l
各呼び出しに改行文字を追加し、入力ファイルを 1 行ずつ読み込み、与えられたスクリプトを各行に適用するように指示します。print
-n
perl
-e
@k=split(/["|]/,$F[6]);
:7番目のフィールドを"
orに分割して|
配列として保存します@k
。これがIPになります。@l=grep{/^10\./}@k;
:@k
a で始まるすべてのフィールドを配列に保存します。10
@l
print "$F[0] @l"
:最初のフィールドとその中のすべての内容を印刷します@l
。sed 's/"//g'
:引用符を削除します。入力ラインは他のものが実行される前に分割されるため、perl
他のプログラムを使用する方が簡単です。
一時配列変数を使用せずにPerlスクリプトを短縮することもできます。
perl -F, -lane 'print "$F[0] ", join " ", grep{/^10\..*/} split(/["|]/,$F[6])' file