1

I would like to change a file so that column N+1 would be put at the end of column N for each N = odd number. For instance, if I had a file with 4 columns, the column 2 would be pasted at the end of column 1 and the column 4 at the end of column 3.

Example file:

1 2 3 4
1 2 3 4
1 2 3 4

Output file:

1 3
1 3
1 3
2 4
2 4
2 4

My files have ~100 lines and ~60000 columns.

5
  • What do you mean Gilles? That I'm a student? Well no, sorry, I am a research scientist (population genetics), working on Structure software and trying to get the number of polymorphic sites from a file. I managed to get it from a test file except this file transformation that I asked about... Commented Apr 1, 2018 at 9:07
  • The output does not correspond to the description. In the output, column N and N + 2 are kept together. Commented Apr 1, 2018 at 9:09
  • Yes, not clear. Commented Apr 1, 2018 at 9:10
  • My apologies if that is not clear. I said that I want column N+1 pasted at the end of column N and N only is an ODD number. So column 2 should be found at the end of column 1, and column 4 at the end of column 3 and so on. But column 1, 3 and all other odd number columns don't move! Commented Apr 1, 2018 at 9:12
  • Please take a look at: What should I do when someone answers my question? Commented Apr 1, 2018 at 11:30

2 Answers 2

1

With bash:

#!/bin/bash

for c in 0 1; do
  while read -r -a columns; do
    for((i=$c; i<${#columns[@]}; i+=2)); do
      echo -n "${columns[$i]} "
    done
    echo
  done < file
done

Output:

1 3 
1 3 
1 3 
2 4 
2 4 
2 4 
0
0

Here's some fairly cryptic awk:

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

The first time you process the file, NR > FNR will be false, or 0.
The second time you process the file, NR > FNR will be true, or 1.


This one requires a single pass through the file, but you have to keep half the file in memory:

awk '
    {
        for (i=1; i<NF; i+=2) {
            printf "%s ", $i
            row[NR] = row[NR] $(i+1) " "
        }
        print ""
    }
    END {
        for (i=1; i<=NR; i++) print row[i]
    }
' file

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.