假设我有 3 条记录:
P1||1234|
P1|56001||
P1|||NJ
我想将这 3 条记录合并为具有所有属性的一条记录。最终记录:
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
用“|”分割行 分隔符并将每个字段打印到一行。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
在您的示例中,您拥有的第一行,您拥有1234
的第二行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