3 つのレコードがあるとします。
P1||1234|
P1|56001||
P1|||NJ
これらの 3 つのレコードを、すべての属性を持つ 1 つにマージしたいと考えています。最終記録 :
P1|56001|1234|NJ
Unix/Linux でこれを達成する方法はありますか?
bash、awk、sedなどで解決策を尋ねると仮定します。次のようなものを試すことができます
$ cat test.txt
P1||1234|
P1|56001||
P1|||NJ
$ cat test.txt | awk -F'|' '{ for (i = 1; i <= NF; i++) print $i }' | egrep '.+' | sort | uniq | awk 'BEGIN{ c = "" } { printf c $0; c = "|" } END{ printf "\n" }'
1234|56001|NJ|P1
簡単に言えば、awk
「|」で行を分割します 区切り記号を付けて、各フィールドを 1 行に出力します。egrep
空行を削除します。その後、複数の属性sort
をuniq
削除します。最後にawk
、行を「|」でマージします セパレーター。
アップデート:
私の理解が正しければ、これがあなたが求めているものです。
$ cat test.txt | awk -F'|' '{ for (i = 1; i <= NF; i++) if($i) col[i]=$i } END{ for (i = 1; i <= length(col); i++) printf col[i] (i == length(col) ? "\n" : "|")}'
P1|56001|1234|NJ
あなたの例では、あなたが持っている1行目、あなたが持っている1234
2行目56001
。
56001
最終結果の理由がわかりません1234
。タイプミス/間違いだと思います。
awk-oneliner は仕事をすることができます:
awk -F'|' '{for(i=2;i<=NF;i++)if($i)a[$1]=(a[$1]?a[$1]"|":"")$i}END{print $1"|"a[$1]}'
あなたのデータで:
kent$ echo "P1||1234|
P1|56001||
P1||NJ"|awk -F'|' '{for(i=2;i<=NF;i++)if($i)a[$1]=(a[$1]?a[$1]"|":"")$i}END{print $1"|"a[$1]}'
P1|1234|56001|NJ