Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

inputfile:is2.txt

10.39.5.41,A1,B1
10.39.5.41,A2,B2
10.39.5.41,A3,B3
10.39.5.41,A4,B4
10.39.5.41,A5,B5
10.39.5.41,A6,B6

script :

#!/bin/bash
second_column="OOOOOOO"    # OOOOOOO will be added to every second column
third_column="XXXXXXXX"    # XXXXXXXX will be added to every third column

awk -v second="$second_column" -v third="$third_column" 'BEGIN { FS="," }
                             {
                                if(a[$1])
                                {a[$1]=a[$1]";second"$2";third"$3}
                                 else
                                {a[$1]=a[$1]second$2";"third$3}}
                             END{for (i in a)print i";"a[i];}' <  is2.txt

output:
[root@testgfs2 test]# ./testawk.awk
10.39.5.41;OOOOOOOA1;XXXXXXXXB1;secondA2;thirdB2;secondA3;thirdB3;secondA4;thirdB4;secondA5;thirdB5;secondA6;thirdB6

why the shell variables(second_column,third_column) are not being reflected for the complete output and just for the first line.whats wrong?

expected output:

10.39.5.41;OOOOOOOA1;XXXXXXXXB1;OOOOOOOA2;XXXXXXXXB2;OOOOOOOA3;XXXXXXXXB3;OOOOOOOA4;XXXXXXXXB4;OOOOOOOA5;XXXXXXXXB5;OOOOOOOA6;XXXXXXXXB6

More over,is there anyway to generalize this for n number of columns say n = 100

share|improve this question
    
It's much easier to just use sed(1) to do this replacement. BTW, in your '-quoted script, the shell variables won't be interpolated at all. –  vonbrand Feb 25 '13 at 16:03
    
can you show me then, and what if the ist columns had differnt inputs and i wanted the data to be organized for each value of the first column somehting like 10.10.10.10;OOOOOOOA1;XXXXXXXXB1;OOOOOOOA2;XXXXXXXXB2;OOOOOOOA3;XXXXXXXXB3 and on the onther line 20.20.20.20;OOOOOOOA1;XXXXXXXXB1;OOOOOOOA2;XXXXXXXXB2;OOOOOOOA3;XXXXXXXXB3 and how would i generalize it –  munish Feb 26 '13 at 6:20
add comment

1 Answer

up vote 5 down vote accepted

Here's the awk code with recommended spacing and indention, can you see the problem?

BEGIN { FS = "," }

{
  if(a[$1])
    a[$1] = a[$1] ";second" $2 ";third" $3
  else
    a[$1] = a[$1]second $2 ";" third$3
}

END {
  for (i in a)
    print i ";" a[i]
}

You quoted second and third in the if clause.

Guessing from your expected output, you could do it like this:

awk -v c2='OOOOOOO' -v c3='XXXXXXXX' -v FS=, -v OFS=';' -v ORS=';' '
  !f { 
    printf "%s", $1
    f=1
  } 
  {
    $1 = ""
    $2 = c2 $2
    $3 = c3 $3
  } 
  1
' | sed 's/;;/;/g; s/;$//'

Output:

10.39.5.41;OOOOOOOA1;XXXXXXXXB1;OOOOOOOA2;XXXXXXXXB2;OOOOOOOA3;XXXXXXXXB3;OOOOOOOA4;XXXXXXXXB4;OOOOOOOA5;XXXXXXXXB5;OOOOOOOA6;XXXXXXXXB6

To generalize this approach, you could pass in the bits to prepend through a string and split it into an awk array. Then use a for-loop instead of explicit column variables:

awk -v prepends='OOOOOOO XXXXXXXX' -v FS=, -v OFS=';' -v ORS=';' '
  BEGIN { split(prepends, cn, / +/) } 

  !f { 
    printf "%s", $1
    f=1
  } 

  { 
    $1 = ""
    for(i=1; i<=NF; i++) 
      $i = cn[i-1] $i
  }
  1' | sed 's/;;/;/g; s/;$//'
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.