使用awk检查来自不同行的变量

时间:2011-09-21 15:29:12

标签: linux shell unix awk sh

如果匹配,我想使用awk将多行不同长度的值组合成一行。在第一个字段的以下示例匹配值中, 将第二个字段中的值聚合到一个列表中。

输入,示例csv:

222;a;DB;a
222;b;DB;a
555;f;DB;a
4444;a;DB;a
4444;d;DB;a
4444;z;DB;a

输出:

222;a|b
555;f
4444;a|d|z

如何编写awk表达式(可能是其他一些shell表达式)来检查第一个字段值是否与下一行/上一行匹配,然后打印由管道聚合和分隔的第二个字段值列表?

5 个答案:

答案 0 :(得分:2)

awk '
  BEGIN {FS=";"}
  { if ($1==prev) {sec=sec "|" $2; }
    else { if (prev) { print prev ";" sec; };
           prev=$1; sec=$2; }}
  END { if (prev) { print prev ";" sec; }}'

根据您的要求,这将检查连续的行。

答案 1 :(得分:1)

这个oneliner工作吗?

 awk -F';' '{a[$1]=a[$1]?a[$1]"|"$2:$2;} END{for(x in a) print x";"a[x]}' file

在这里测试:

kent$  cat a
222;a;DB;a
222;b;DB;a
555;f;DB;a
4444;a;DB;a
4444;d;DB;a
4444;z;DB;a

kent$  awk -F';' '{a[$1]=a[$1]?a[$1]"|"$2:$2;} END{for(x in a) print x";"a[x]}'  a
555;f
4444;a|d|z
222;a|b

如果您想对其进行排序,请在最后添加|sort

答案 2 :(得分:0)

假设您已将字段分隔符(-F)设置为; :

{
   if ( $1 != last ) { print s; s = ""; }
   last = $1;
   s = s "|" $2;
} END {
   print s;
}

第一行和第一个字符略有错误,但这对读者来说是一个练习:-)。两个简单的if就足以解决这个问题了。

(编辑:错过最后一行。)

答案 3 :(得分:0)

稍微复杂,但是做了这件事:

awk -F';' \
'{
  if (a[$1]) {
    a[$1]=a[$1] "|" $2
  } else {
    a[$1]=$2
  }
 }
 END {
   for (k in a) {
     print k ";" a[k]
   }
 }' file

答案 4 :(得分:0)

这应该有效:

命令:

awk -F';' '{if(a[$1]){a[$1]=a[$1]"|"$2}else{a[$1]=$2}}END{for (i in a){print i";" a[i] }}' fil

输入:

222;a;DB;a
222;b;DB;a
555;f;DB;a
4444;a;DB;a
4444;d;DB;a
4444;z;DB;a

输出:

222;a|b
555;f
4444;a|d|z