alvas
alvas

Reputation: 122148

Shuffling columns in a delimited file

I have a file:

$ cat test.txt 
a   b   c
d   e   f
x   y   z

I could do this in Python to shuffle the columns:

import random

with open('test.txt', 'r') as fin:
    with open('test-shuffle.txt', 'w') as fout:
         for line in fin:
             line = line.strip().split('\t')
             random.shuffle(line)
             fout.write('\t'.join(line) + '\n')

[out]:

$ cat test-shuffle.txt 
b   c   a
e   d   f
x   y   z

But is there a way to do it on the command line? Maybe with cut, awk, sed, etc.?

Also, if I want to only shuffle specific columns, is that possible on the command line too, e.g. if I only want to shuffle the 2nd and 3rd column:

import random

with open('test.txt', 'r') as fin:
    with open('test-shuffle.txt', 'w') as fout:
         for line in fin:
             line = line.strip().split('\t')
             first , second, third = line
             second_third = [second, third]
             random.shuffle(second_third)
             fout.write('\t'.join([first] + second_third) + '\n')

Upvotes: 2

Views: 476

Answers (3)

karakfa
karakfa

Reputation: 67507

awk to the rescue!

awk 'NR==1 {srand(); 
            for(i=1;i<=NF;i++) a[i]=i; 
            for(i=1;i<=NF;i++) 
              {j=1+int((NF-i)*rand()); 
               t=a[i]; a[i]=a[NF-j]; a[NF-j]=t}}   
           {for(i=1;i<=NF;i++) printf "%s",$(a[i]) FS; 
            print ""}'

Upvotes: 2

Michael Vehrs
Michael Vehrs

Reputation: 3363

It can be done using coreutils:

xargs -l shuf -e < test.txt| xargs -l3

Upvotes: 3

Alex L
Alex L

Reputation: 1114

You didn't mention perl, but perl is a superset of cut, awk, sed. It's the Swiss Army Chainsaw of programming languages!

$ cat /tmp/test.tsv
a       b       c
d       e       f
x       y       z
$ perl -mList::Util -aln -F'\t' -e 'print join("\t", List::Util::shuffle @F)' < /tmp/test.tsv
b       a       c
d       f       e
y       x       z
$ perl -mList::Util -aln -F'\t' -e 'print join("\t", List::Util::shuffle @F)' < /tmp/test.tsv
c       a       b
e       d       f
x       z       y

Oh, the second part:

$ perl -mList::Util -aln -F'\t' -e 'print join("\t", $F[0], List::Util::shuffle @F[1..2])' < /tmp/test.tsv
a       c       b
d       f       e
x       y       z

Upvotes: 5

Related Questions