Randomize columns in CSV file

Hi there, friends!

Writing exams again! This time my wish would be to randomize certain columns in a csv file. Given a file containing records consisting of 3 columns tab-separated:

A B C
A B C
A B C

I would love to get the columns of each record in random order...separated by a tab as well.

C B A
B C A
A C B
...

Love you all out there!

PS: This is not homework, I am an English teacher rewriting tests for my students.

Do not post classroom or homework problems in the main forums. Homework and coursework questions can only be posted in this forum under special homework rules.

Please review the rules, which you agreed to when you registered, if you have not already done so.

More-than-likely, posting homework in the main forums has resulting in a forum infraction. If you did not post homework, please explain the company you work for and the nature of the problem you are working on.

If you did post homework in the main forums, please review the guidelines for posting homework and repost.

Thank You.

The UNIX and Linux Forums.

I promise it is not homework...on the contrary, I am a teacher.

awk -v rn=$RANDOM '
BEGIN {
   srand(rn);
}
{
 f=NF;
 for (i=1 ; i<=f; i++) a=i;
 n=1;
 while (n<4) {
    d=int((rand() * f+1));
    d=int((rand() * f+1));
    if (d > 0 && d < f+1) {
       if (d in a && a[d]) {a1[n]=$d; delete a[d]; n++;}
    }
 }
 $0="";
 for (i=1; i<(f+1); i++) $0=$0 OFS a1;
 $1=$1;
 print;
 for (i in a1) delete a1;
 for (i in a) delete a;
}

' OFS="\t" infile
1 Like

Uff, thanks rdrtx1m but I am not sure how to use this code...i am such a newbie. ...still trying to figure it out...

Try also

while read TMP; do echo $(shuf -e $TMP) | tr ' ' '\t' ; done <file
C    B    A
A    C    B
A    B    C
1 Like

Yep, both scripts work...as log as the options to be shuffled are single letters/words (eg. A, B...just, never, ever...) but, what about if the options are groups or words?

Option A Option B Option C
I was I have been I will be
She's done She'll do She'd do
... ... ...

...and in case I had 4 options?

Thank you so much to you mates. :slight_smile:

The field / group separator must be different from the word separator, e.g. spaces between words, <TAB>s between groups. Seems to be easier in awk than in pure shell, but try (recent shell, e.g. bash 4 required)

while IFS="    " read -a TMP; do shuf -i0-$((${#TMP[@]}-1)) | while IFS="    " read LN; do printf "%s\t" "${TMP[$LN]}"; done; printf "\n"; done <file
B    D    A    C    
B    E    A    C    D    
B    C    A    
Option B    Option C    Option A    
I have been    I was    I will be    
She will have done    She'll do    She'd do    She's done    

Watch out, the IFS is being set to a <TAB> char.

1 Like

It worked!! It worked!! Yep! :slight_smile:

A long story as I am working on a Mac. First you have to install HOMEBREW brew install coreutils , change the order shuf to gshuf .
Also, you have to update your BASH version to 4 (I followed this link Upgrade to bash 4 in Mac OS X � clubmate.fi, then go on scripting.

Great job!...and done quickly! Super!:slight_smile:

---------- Post updated at 02:55 AM ---------- Previous update was at 02:53 AM ----------

As I see it it will shuffle any number of columns, won't it?

I guess so, as long as word seperators and field sep. are clearly distinguished. Why don't you give it a shot?

Yes!

file contents:

you / you do / do you / you did
she got / did she get / did she got / she gotten
are makeing / making / are making / is making
usually have / has usually / usually has / have usually

$ ./random

result:

you / you do / do you / you did
did she got / she gotten / she got / did she get
are making / are making / is making / making
usually has / usually have / has usually / have usually

That's it!

The result doesn't look too good - is that an artifact that happened when dragging / dropping the text?

This is how it looks like if I run it on my system:

you do	you	do you	you	
she gotten	did she got	did she get	she got	
are makeing	is making	are making	making	
usually has	has usually	have usually	usually have	

input:

you    you do    do you    you did
she got    did she get    did she got    she gotten
are makeing    making    are making    is making
usually have    has usually    usually has    have usually

output:

you do    do you    you did    you    
she gotten    did she got    she got    did she get    
are making    making    are makeing    is making    
usually has    usually have    has usually    have usually