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)

freely
  • 1
  • 2
  • 1
    Welcome to U/L. Could you please write the awk command you tried? – Sparhawk May 05 '19 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 05 '19 at 10:15
  • Please add information to the question, not to the comments. – RalfFriedl May 05 '19 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 05 '19 at 12:02

2 Answers2

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.

LeonidMew
  • 250
  • 2
  • 12
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
glenn jackman
  • 84,176
  • 15
  • 116
  • 168
  • 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 06 '19 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 06 '19 at 12:10