0

For example, you have:

name 1 2 3 4 5 6 7 8

With tab delimiter ^

And I want to switch between 2 columns (for example 7th and 8th if you start with 0) so it would look like:

name 1 2 3 4 5 6 8 7

Eventually, it should be probably other column indexes..

I tried using awk but got a lot of errors. Could you explain?

The command I tried was:

awk ' { t = $10; $10 = $9; $9 = t; print > "test2.txt"; } ' test.txt 

It created a new file, but without the tab delimiter. (With space delimiter)

4
  • 1
    Welcome to U/L. Could you please write the awk command you tried?
    – Sparhawk
    May 5, 2019 at 10:09
  • Sure, awk ' { t = $10; $10 = $9; $9 = t; print > "test2.txt"; } ' test.txt It created a new file, but without the tab delimiter. (With space delimiter)
    – freely
    May 5, 2019 at 10:15
  • Please add information to the question, not to the comments.
    – RalfFriedl
    May 5, 2019 at 10:40
  • Not an exact duplicate, but the answer is the same. Also, you have got the column numbers wrong in your command. Subtract one from each number.
    – Sparhawk
    May 5, 2019 at 12:02

2 Answers 2

0

I don't know how to awk this, so here is simple bash script:

#!/usr/bin/env bash

while IFS='' read -r i || [[ -n "$i" ]]; do
  cut -f1,2,3 -z <<<"$i"
  printf '\t'
  cut -f10 -z <<<"$i"
  printf '\t'
  cut -f5,6,7,8,9 -z <<<"$i"
  printf '\t'
  cut -f4 <<<"$i"
done <colinput.txt

"-z" cut option to not print newline. Its not possible to have option -f1,2,3,4,5,6,8,7 as cut not change column position in output. cut default delimiter is tab.

4
  • Thanks, so for example if I want to switch 4th column and 10th column, what should I edit in the command?
    – freely
    May 5, 2019 at 11:18
  • I have update answer to that. First output 1,2,3, then 10, then 5,6,7,8,9, then 4
    – LeonidMew
    May 5, 2019 at 11:24
  • Thanks, now I get it. Will try shortly
    – freely
    May 5, 2019 at 11:26
  • Columns not zero based, starting from 1
    – LeonidMew
    May 5, 2019 at 11:26
0

You just need to specify the delimiters. In awk, the input field separator is the FS variable, and correspondingly the output field separator is OFS. Here are some of the ways to specify these variables:

  1. assign the variables in the BEGIN block:

    awk 'BEGIN {FS = OFS = "\t"} { t = $10; $10 = $9; $9 = t; print } ' test.txt > test2.txt
    
  2. set the variables within the file list after the awk body

    awk '{ t = $10; $10 = $9; $9 = t; print } ' FS='\t' OFS='\t' test.txt > test2.txt
    
  3. using the -F and -v options

    awk -F '\t' -v OFS='\t' '{ t = $10; $10 = $9; $9 = t; print } ' test.txt > test2.txt
    

Additionally, to specify the column numbers you can use these same techniques. I prefer to use -v because it's the cleanest way to pass a shell variable into an awk variable.

awk -F '\t' -v OFS='\t' -v a=9 -v b=10 '{
    t  = $a
    $a = $b
    $b = t
    print 
}' test.txt > test2.txt
2
  • The last awk script seems very simple to understand, but it does something else. Every 9th column, it copies the first columns instead of just switching
    – freely
    May 6, 2019 at 11:56
  • Eventually, I did manage to run it with a=10 and b=9, thanks a lot!! The script is easy to understand
    – freely
    May 6, 2019 at 12:10

Not the answer you're looking for? Browse other questions tagged .