zara
zara

Reputation: 1108

How to put different separators between columns in a file in linux?

I have a huge data file in which there is space between columns as a separator. I wan to put tab between every other 2 coloumn and the need to be 2 space between each pair of columns. As a small example to clarify what I mean:

input file:

   1 1 1 1 2 1 2 2 2 1 1 1 2 2 1 2 

   1 1 1 1 1 1 2 2 1 1 1 1 2 2 2 2 

   1 1 1 1 1 1 2 2 1 1 1 1 2 2 2 2

I want the output file be like:

1  1    1  1    2  1    2  2    2  1    1  1    2  2    1  2
1  1    1  1    1  1    2  2    1  1    1  1    2  2    2  2
1  1    1  1    1  1    2  2    1  1    1  1    2  2    2  2

Any suggestion please? Note that the real file has more than 50,000 columns and rows.

Upvotes: 0

Views: 187

Answers (5)

Ed Morton
Ed Morton

Reputation: 203985

$ awk '{for (i=2;i<=NF;i+=2) printf "%s  %s%s", $(i-1), $i, (i<NF ? "\t" : ORS)}' file
1  1    1  1    2  1    2  2    2  1    1  1    2  2    1  2
1  1    1  1    1  1    2  2    1  1    1  1    2  2    2  2
1  1    1  1    1  1    2  2    1  1    1  1    2  2    2  2

Upvotes: 1

Walter A
Walter A

Reputation: 20022

You would like a simple sed command like

echo "1 1 1 1 2 1 2 2 2 1 1 1 2 2 1 2" |
   sed 's/ \([^ ]\) /  \1   /g'

This one has a little bug that is difficult to see with the spaces. I will use a x first:

echo "1 1 1 1 2 1 2 2 2 1 1 1 2 2 1 2" |
   sed 's/ \([^ ]\) /xx\1xxx/g'
# Result:
1xx1xxx1xx1xxx2xx1xxx2xx2xxx2xx1xxx1xx1xxx2xx2xxx1 2

Wow! When you have an even number of fields the last separator is skipped. You can patch it (now I will use a y for marking the patch).

echo "1 1 1 1 2 1 2 2 2 1 1 1 2 2 1 2" | 
   sed 's/ \([^ ]\) /xx\1xxx/g; s/\([^ ]\) \([^ ]*\)$/\1yy\2/'
# Result
1xx1xxx1xx1xxx2xx1xxx2xx2xxx2xx1xxx1xx1xxx2xx2xxx1yy2

Now replace the temp x and y with spaces:

echo "1 1 1 1 2 1 2 2 2 1 1 1 2 2 1 2" |
   sed 's/ \([^ ]\) /  \1   /g; s/\([^ ]\) \([^ ]*\)$/\1  \2/'

Upvotes: 0

karakfa
karakfa

Reputation: 67507

another awk

$ awk -v OFS="  " '{for(i=2;i<=NF;i+=2)$i=$i" "}1' file

Upvotes: 2

anubhava
anubhava

Reputation: 785481

You can use this awk:

awk '{printf "%s", $1;
      for (i=2; i<=NF; i++) printf "%s", (i%2 ? "   " : "  ") $i; print ""}' file

1  1   1  1   2  1   2  2   2  1   1  1   2  2   1  2
1  1   1  1   1  1   2  2   1  1   1  1   2  2   2  2
1  1   1  1   1  1   2  2   1  1   1  1   2  2   2  2

Upvotes: 0

bobah
bobah

Reputation: 18864

Something like cat file.name | perl -pe 's/([^ ]+ [^ ]+) /\1 /g'

Upvotes: 0

Related Questions