假设我有3条记录:
P1||1234|
P1|56001||
P1|||NJ
我想将这3条记录合并为一条具有所有属性的记录。最终记录:
P1|56001|1234|NJ
有没有办法在Unix / Linux中实现这一目标?
答案 0 :(得分:1)
我假设你用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
答案 1 :(得分:0)
在您的示例中,第一行是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