私のファイルは次のとおりです。
pw1jc5ssyt6hx618,254343
ysezaratlycpuggl,254333
pht92h4adr3mrbz3,254343
hguvgstqxu3gowfg,254344
gqjp2rsjmk1a2v9c,254333
twdzyi2ddbnrfknd,254333
gcmj7krrx5x6nf8r,254341
tpqorqbyrg1nmm7s,254333
alnac47rt8d4ege3,254343
-
2番目の列に基づいてこのファイルを区切り記号にマージして、結果を次のようにしたいと思います。
254343,pw1jc5ssyt6hx618-pht92h4adr3mrbz3-alnac47rt8d4ege3
254333,ysezaratlycpuggl-gqjp2rsjmk1a2v9c-twdzyi2ddbnrfknd-tpqorqbyrg1nmm7s
254344,hguvgstqxu3gowfg
254341,gcmj7krrx5x6nf8r
ベストアンサー1
awk
あなたの友達です
$ cat 299360
ipw1jc5ssyt6hx618,254343
ysezaratlycpuggl,254333
pht92h4adr3mrbz3,254343
hguvgstqxu3gowfg,254344
gqjp2rsjmk1a2v9c,254333
twdzyi2ddbnrfknd,254333
gcmj7krrx5x6nf8r,254341
tpqorqbyrg1nmm7s,254333
alnac47rt8d4ege3,254343
$ awk -v FS="," '/^$/{next} # for empty line go to next record
{if(NR==1){ # checking for first record
f2[$2]=$1;next} # Adding $1 to array f2 at index $2
else{
if($2 in f2){ # Check if $2 is already an index in f2
f2[$2]=f2[$2]"-"$1;next #appending "-$1" to current value
}
else{
f2[$2]=$1;next
}
}}
END{ # This line will be processed at the end
for(i in f2){ # for all the indexes i in f2
printf "%s,%s\n",i,f2[i] #printing in the desired format
}
}
' 299360
254341,gcmj7krrx5x6nf8r
254333,ysezaratlycpuggl-gqjp2rsjmk1a2v9c-twdzyi2ddbnrfknd-tpqorqbyrg1nmm7s
254343,pw1jc5ssyt6hx618-pht92h4adr3mrbz3-alnac47rt8d4ege3
254344,hguvgstqxu3gowfg
説明する
FS=","
- FSはawkの組み込み変数としてフィールド区切り文字を表します。フィールド区切り記号を次に設定すると、区切り文字に,
設定されます。,
$1
$2
などでフィールドにアクセスできます。- awkスクリプトは一重引用符で囲まれています。
'awk-script-goes-here'
NR
レコード番号(現在処理中のレコード番号)を表すawk組み込み変数。デフォルトでは、各行はレコードです。- field2でインデックス付けされた連想配列(例:)を
f2[$2]=$1
設定しています。f2
$2
$2 in f2
インデックスが配列にすでに存在することを確認してください。- そして自明
if-else
です。printf
- awkのブロックは
END
最後にのみ実行されます。つまり、すべてのレコードが処理された後に実行されます。 for(i in f2)
awkで連想配列を解析するために使用されるforループ構造。これは別の表現で、for every index i in f2 do something
- 上記の
for
ループは配列を順番に印刷しないことがあります。ただし、sort
bashコマンドを使用して配列を並べ替えることはできます。 next
後続のコマンドを処理せずに次のレコードに移動します。/pattern/
awkのパターンチェック;パターンは^$
空白行をチェックします。
引用する
awkの専門家になりたいなら、効果的なawkプログラミング必ず読むべき本です。
醜い一行
awk -v FS="," '/^$/{next}{if(NR==1){f2[$2]=$1;next}else{if($2 in f2){f2[$2]=f2[$2]"-"$1;next}else{f2[$2]=$1;next}}}END{for(i in f2){printf "%s,%s\n",i,f2[i]}}' 299360
メモ:理想的には、awkスクリプトで改行をハードコーディングすることはお勧めできませんprintf "%s,%s\n",i,f2[i]
。printf "%s,%s\n",i,f2[i];print
さらなる移植性のために。