awk独立3列

awk独立3列

次のファイルがあります(列はタブで区切られ、スペースを含めることができます)。

    0637    apple    8528    1392    orange    1390    8528    unknown fruit    7537    1039    banana    1892    0989    pineapple    7537    8528    melon    7537    8528    grape    7537    8528    (null)    (null)

結果を得るには、3つの列ごとに分割してgrepする必要があります(大容量ファイルではgrepよりはるかに高速であるため、[0-9]$これを使用します)。awk

0637    apple    8528
1392    orange    1390
8528    unknown fruit    7537
1039    banana    1892
0989    pineapple    7537
8528    melon    7537
8528    grape    7537

今私にはこれがあります美しいこれを行うコマンド:

awk -F\\t '{print $2 "\t" $3 "\t" $4 "\n" $5 "\t" $6 "\t" $7 "\n" $8 "\t" $9 "\t" $10 "\n" $11 "\t" $12 "\t" $13 "\n" $14 "\t" $15 "\t" $16 "\n" $17 "\t" $18 "\t" $19 "\n" $20 "\t" $21 "\t" $22 "\n" $23 "\t" $24 "\t" $25}' filename | awk '/[0-9]$/'

cutまた、同じことを行う醜いコマンドもあります。私はまだawkを学んでいるので、これを行うより合理的な方法があると確信しています。さらに、私は多分超過すると問題が発生します$25。助けてください?

答え1

これは働きます:

$ cat splitnum.awk
#!/bin/awk -f
BEGIN {
    FS = OFS = "\t"
}
{
    for ( i = 1; i < NF; i = i + 3) {
        if ( $(i+2) ~ /[0-9]+/ ) {
            print $i, $(i+1), $(i+2)
        }
    }
}
$ awk -f splitnum.awk filename

または、1行にすべて記入してください。

awk 'BEGIN{FS=OFS="\t"}{for (i=1;i<NF;i=i+3){if ($(i+2) ~ /[0-9]+/) {print $i, $(i+1), $(i+2)}}}' filename

デフォルトでは、データフィールドを一度に3つずつ繰り返しながら、3番目のフィールドが数値で構成されていることを確認します。

答え2

フィールドが 1 つ以上のタブで区切られ、各フィールドにタブではなく空白が含まれていると仮定すると、次のようになります。

( IFS=$'\t'; printf '%s %s %s\n' $(<input_file) )

(サブシェルは便利で、IFS呼び出しシェルを変更する必要はありません。)

または、フィールドが 1 つ以上のスペースとタブで区切られ、各フィールドにスペースやタブがない場合は、次のようになります。

printf '%s %s %s\n' $(<input_file)

答え3

awk -F'\t' '{for(i=1;i<=NF;i++)if(!(i%3))$i=$i "\n"}1' file

答え4

奇妙な嫌いな人のために:

perl -pe 's/(\d+)\s+(\d+)/$1\n$2/g' | 
perl -lnpe 's/^\s*(\d+)\s+([^\d]+?)\s+(\d+).*/$1\t$2\t$3/' |
egrep '[0-9]$'

関連情報