4

I have a file in the following format:

s1,23,789  
s2,25,689

and I would like to transform it into a file in the following format:

s1      23  789  
s2      25  689

i.e 6 white spaces between the 1st and 2nd column and only 3 white spaces between the 2nd and 3rd column?

Is there a quick way of pulling this off using sed or awk?

6

Something along these lines should do it:

awk 'BEGIN{IFS=","} {printf("%s      %s   %s\n", $1, $2, $3)}' input_file

And equivalently and more terse (from the comments):

awk -F ',' '{printf("%s      %s   %s\n", $1, $2, $3)}' input_file
  • That's assuming that the data fields are of constant width, which I doubt. – Julie Pelletier Jan 17 '17 at 1:37
  • OP was very specific about 6 spaces and 3 spaces.... – Stephen Rauch Jan 17 '17 at 1:40
  • OK. I guess so. Then you nailed it. – Julie Pelletier Jan 17 '17 at 1:43
  • Cosnider using -F ',' instead of the BEGIN statement. Makes it shorter – Sergiy Kolodyazhnyy Jan 17 '17 at 4:30
  • 1
    Also, the ;next is unnecessary, since there are no blocks or tests after it – muru Jan 17 '17 at 5:02
4

AWK

Alternative awk with sprintf():

$ awk -F ',' '{long=sprintf("%6s"," ");short=sprintf("%3s"," "); print $1long$2short$3 }' input.txt 
s1      23   789  
s2      25   689

And variation on the theme with regular printf():

$ awk -F ',' '{printf "%s%6s%s%3s%s\n",$1," ",$2," ",$3}' input.txt                                                      
s1      23   789  
s2      25   689

Yet another variation on the theme of sprintf(), but with sub() and gsub() functions. Since sub() edits only first match, it's convenient for us to use it to replace first comma with 6 spaces, and the other one with 3

$ awk '{sub(/\,/,sprintf("%6s",""));gsub(/\,/,sprintf("%3s",""));};1' input.txt                                          
s1      23   789  
s2      25   689

For the folks who like alternatives, here's other approaches:

Perl

$ perl -F',' -lane "print @F[0],' 'x6,@F[1],' 'x3,@F[2]"  < input.txt                                                    
s1      23   789  
s2      25   689

Python

$ python -c 'import sys;lines=[l.strip().split(",") for l in sys.stdin];print "\n".join([ i[0]+" "*6+i[1]+" "*3+i[2] for i in lines])' < input.txt
s1      23   789
s2      25   689

SED

$ sed -e 's/,/      /' -e 's/,/   /'  input.txt                                                                          
s1      23   789  
s2      25   689

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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