awkを使用して2つの文字列のいずれかを含むテーブルのすべてのフィールドを印刷する方法

awkを使用して2つの文字列のいずれかを含むテーブルのすべてのフィールドを印刷する方法

行が多く、行ごとに列数が可変なテーブルがあります。

各行で最初のフィールドと2つの文字列のうちの1つを含むすべてのフィールドのみを印刷したい(この場合は、dogとcowという単語を含むすべてのフィールドが必要です)。

たとえば、

A   dog999   dog284   cow284   pig383   pig234   cow432   chicken432
B   cow394   cow432   cow345   dog983   pig345   chicken532 
C   dog847   pig357   pig236   cow395   dog496
D   dog392   cow237   cow749

希望の出力:

A   dog999   dog284   cow284   cow432   
B   cow394   cow432   cow345   dog983   
C   dog847   cow395   dog496
D   dog392   cow237   cow749

これまで私はawkを使用していました。

awk -v OFS='\t' '{for (i = 1; i <= NF; i++) {if ($i ~ /dog/) print $1,$i; else if ($i ~ /cow/) print $1,$i} }' file.txt

ただし、これにより各フィールドに2つの文字列のうちの1つが1行を占有します。

ベストアンサー1

perl回避策が大丈夫な場合:

$ cat ip.txt 
A   dog999   dog284   cow284   pig383   pig234   cow432   chicken432
B   cow394   cow432   cow345   dog983   pig345   chicken532 
C   dog847   pig357   pig236   cow395   dog496
D   dog392   cow237   cow749

$ perl -lane 'print join("\t",$F[0],grep {/cow|dog/} @F[1..$#F])' ip.txt 
A   dog999  dog284  cow284  cow432
B   cow394  cow432  cow345  dog983
C   dog847  cow395  dog496
D   dog392  cow237  cow749
  • -a入力行をスペースに分割して@F配列に保存
  • -l入力から改行文字を削除して印刷するときにもう一度追加してください。
  • join\t印刷するとき、
  • $F[0],grep {/cow|dog/} @F[1..$#F]配列の最初の要素とcow一致するすべての要素、またはdog
  • また利用可能ですperl -lape'$_=join"\t",shift(@F),grep/cow|dog/,@F'。ここでは配列の最初の要素をshift削除して返し、結果を に割り当てると最後に無料オプションが印刷されます(ヒント)。@F$_-pスティーブン・チャジェラス)


以下を含まないかcow無視されるdog行:

perl -lane 'print join("\t",$F[0],grep {//} @F[1..$#F]) if /cow|dog/' ip.txt 

おすすめ記事