开发者

Check variables from different lines with awk

I want to combine values from multiple lines with different lengths using awk into one line if they match. In the following sample match values for first field, aggregating values from second field into a list.

Input, sample 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

Output:

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

How can I write an awk expression (maybe some other shell expression) to check if the first field value match with the next/previous开发者_开发问答 line, and then print a list of second fields values aggregated and separated by a pipe?


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; }}'

This, as you requested, checks the consecutive lines.


does this oneliner work?

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

tested here:

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

if you want to keep it sorted, add a |sort at the end.


Slightly convoluted, but does the job:

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


Assuming that you have set the field separator ( -F ) to ; :

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

The first line and the first character are slightly wrong, but that's an exercise for the reader :-). Two simple if's suffice to fix that.

(Edit: Missed out last line.)


this should work:

Command:

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

Input:

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

Output:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜