4

現時点で awk を学習しようとしていますが、特定のタスクを実行したいと考えています。私の質問は、以前に投稿されたもの( awk を使用して列を行に転置する)と範囲が似ていますが、私のデータではうまくいきません。私はその理由を解明しようとしてきましたが、それは非常に単純だと確信しています。

2 つのフィールドしかないタブ区切りのテーブルに大きなデータがあります (以下の例)。

1101\t7778
1101\t7755
1101\t8889
1101\t6789
2300\t1220
4000\t2333
4000\t7555
4000\t9000
4000\t1111

フィールドが一致したときに、2番目のフィールドを行に追加したいと考えています。望ましい出力は次のようになります。

1101\t7778\t7755\t8889\t6789
2300\t1220
4000\t2333\t7555\t9000\t1111

可能であれば、コマンド内のすべての部分の説明を取得して、将来理解できるようにしたいと思います。前もって感謝します。

4

5 に答える 5

5
awk '    { list[$1] = list[$1] "\t" $2 }
     END { for (i in list) printf "%s%s\n", i, list[i] }' data

list最初の行は、タブと 2 番目のフィールドをによってインデックス付けされた要素に追加します$1。2 行目は、キーと累積された値のリストを出力します。

出力例:

1101    7778    7755    8889    6789
4000    2333    7555    9000    1111
2300    1220

最初の列を並べ替えたい場合は、出力を にパイプできますsort -n。GNU を使用している場合はawk、組み込みの sort 関数も調査できます。

/usr/gnu/bin/awk '    { list[$1] = list[$1] "\t" $2 }
                  END { n = asorti(list, indexes);
                        for (i = 1; i <= n; i++)
                            printf "%s%s\n", indexes[i], list[indexes[i]]
                      }' data

ソートされた出力:

1101    7778    7755    8889    6789
2300    1220
4000    2333    7555    9000    1111
于 2013-05-25T04:27:29.180 に答える
3

このバージョンは、ファイル全体をメモリに格納することにはなりません。キーの順序を再配置することもありません。

awk -F '\t' '
    $1 != prev {
        if (prev) print ""
        printf "%s", $1
        prev=$1
    }
    {printf "%s%s", FS, $2}
    END {print ""}
' f
1101    7778    7755    8889    6789
2300    1220
4000    2333    7555    9000    1111
于 2013-05-25T18:07:17.760 に答える
3

abasu の純粋なbashバージョンの要求:

#!/bin/bash

declare -A hash
while read x y; do
  hash[$x]=${hash[$x]}"\t"$y
done <<XXX
1101    7778
1101    7755
1101    8889
1101    6789
2300    1220
4000    2333
4000    7555
4000    9000
4000    1111
XXX

for i in ${!hash[*]}; { echo -e $i${hash[$i]};}

出力:

2300    1220
1101    7778    7755    8889    6789
4000    2333    7555    9000    1111

here-is-the-document では、列と出力列の間にタブ文字があります。-e出力後の最後の行から が削除された場合echo:

2300\t1220
1101\t7778\t7755\t8889\t6789
4000\t2333\t7555\t9000\t1111
于 2013-05-25T13:02:28.533 に答える