将多个记录合并到具有所有非空值的唯一记录中

时间:2013-05-20 10:26:43

标签: linux shell unix

假设我有3条记录:

P1||1234|
P1|56001||
P1|||NJ

我想将这3条记录合并为一条具有所有属性的记录。最终记录:

P1|56001|1234|NJ

有没有办法在Unix / Linux中实现这一目标?

2 个答案:

答案 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删除空行。之后,sortuniq会删除多个属性。最后,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

我不明白为什么在你的最终结果中,560011234之前。我认为这是一个错字/错误。

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