ほぼ2000行のファイルがあります。ファイル形式は次のとおりです。
12 34
0 2
2 3
7 9
1 2
306 237
0 9
12 134
2 7
2 9
306 3
重複した最初の列を削除し、2番目の列で構成するbashスクリプトを作成しようとしています。次のような結果を期待しています。
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 237 3
いくつかのコードを試しましたが、目的の結果が得られませんでした。どうすればこれを達成でき、何を使うべきですか?
答え1
重複行を使用sort
およびuniq
削除してから、awk
最初の列の値で索引付けされた配列を使用してから、2番目の列を配列の各値に追加できます。次のようになります。
sort test.txt | uniq | awk '{if(col[$1])col[$1]=col[$1]" "$2; else col[$1]=$2;}; END{for (i in col) print i, col[i]}'
test.txt
入力ファイルです。
正しい値を持つ配列に新しい列を追加する前に、配列が空であることを確認する必要があります。値の間にスペースを追加するだけです。
答え2
私達は一緒にawk
できます:
awk '{ found[$1]= (found[$1]? found[$1] FS $2: $2); };
END { for (x in found) print x, found[x]; }' infile
2番目の列を同じ最初の列に関連付けて連想配列に保存し、名前をとして指定します。最初の列を印刷しfound
ながら(これを次のように使用します。)END
配列キー私たちは次のようにアクセスします。key
if x
) という名前を付けてから、2 番目の列が結合されます(次からアクセス可能)。array_name[key]
)
答え3
使用datamash
:
$ datamash -s -t ' ' -g 1 collapse 2 <file
0 2,9
1 2
12 34,134
2 3,7,9
306 237,3
7 9
これにより、スペースで区切られたデータを読み取り、並べ替え、2番目の列を最初の列が提供するグループに縮小します。
コンマを空白に置き換えるには、出力を次に渡しますtr , ' '
。
$ datamash -s -t ' ' -g 1 collapse 2 <file | tr , ' '
0 2 9
1 2
12 34 134
2 3 7 9
306 237 3
7 9
行を数字で並べ替えますか?次のアドレスに転送してくださいsort -n
。
$ datamash -s -t ' ' -g 1 collapse 2 <file | tr , ' ' | sort -n
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 237 3
または、最初に数値ソートを実行してから-s
通話から削除しますdatamash
。
$ sort -n <file | datamash -t ' ' -g 1 collapse 2 | tr , ' '
0 2 9
1 2
2 3 7 9
7 9
12 134 34
306 237 3
各行を列ごとに数値で並べ替えるには(最初の列を除く)、元のデータが最初の列だけでなく2番目の列でも並べ替えられていることを確認してください。
$ sort -k 1,1n -k 2,2n <file | datamash -t ' ' -g 1 collapse 2 | tr , ' '
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 3 237
(出力の最後の2行に表示される違いに注意してください。)
答え4
ファイル内の2つのフィールドを数字でソートし、追加の処理のためにGNU awk / sedに渡すと、必要なo / pが得られます。
$ sort -n -k1 -k2 < file \
| awk '
BEGIN { ORS = "" }
prev != $1"" {
if (NR>1) print RS
print
prev = $1
next
}{ print ORS, $2 }
END { print RS }
' -
$ sort -n -k1 -k2 < file \
| sed -Ee '
:a
$!N
/^(\S+)\s.*\n\1\s/s/\n\S+//
ta
P;D
'
出力:
0 2 9
1 2
2 3 7 9
7 9
12 34 134
306 3 237