Print all other variables in awk

I'm trying to write a quick awk script that converts strings in this format:

AAAA BBBB CCCC DDDD...

      

to

CCCC AAAA BBBB DDDD...

      

This is my script:

{ printf "%s %s %s %s", $3, $1, $2, $4 };

      

This works great except when the original input line has more than 4 tokens, in which case the fifth and subsequent tokens are not printed.

I have checked several answers, such as Using awk to print all columns from nth to last , but they rely on setting variables to ""

, which seem to cause problems if these variables are reused later.

Is there an easy way to replace $4

it with something like "substring from $ 4 to end of string"?

+3


source to share


4 answers


In this simple case, you only need:

$ awk '{t=$3; $3=$2; $2=$1; $1=t}1' file
CCCC AAAA BBBB DDDD

      

but in general with GNU awk for gensub()

, \s

and \s

:

$ awk '{print $3, $1, $2, gensub(/^\s*(\S+\s+){3}/,"","")}' file
CCCC AAAA BBBB DDDD

      

gensub()

just skips the first 3 fields and will leave all margins and spaces between fields as-from this point:



$ cat file
AAAA BBBB CCCC DDDD    EEEE    FFFF  GGGG

$ awk '{print $3, $1, $2, gensub(/^\s*(\S+\s+){3}/,"","")}' file
CCCC AAAA BBBB DDDD    EEEE    FFFF  GGGG

      

With other awks, you can do the same with match()+substr()

:

$ awk '{match($0,/^[[:space:]]*([^[:space:]]+[[:space:]]+){3}/); print $3, $1, $2, substr($0,RLENGTH+1)}' file
CCCC AAAA BBBB DDDD    EEEE    FFFF  GGGG

      

or sub()

and a variable:

$ awk '{x=$0; sub(/^[[:space:]]*([^[:space:]]+[[:space:]]+){3}/,"",x); print $3, $1, $2, x}' file
CCCC AAAA BBBB DDDD    EEEE    FFFF  GGGG

      

+6


source


It's not necessarily "easy", but it's not that hard:

{  printf "%s %s %s ", $3, $1, $2;
   for (i=4; i<= NF; ++i) {
       printf "%s ", $i;
   }
   printf "\n";
}

      



Another way, a little smarter:

{ N3 = $3; N2 = $2; N1 = $1;  // capture the fields
  $1 = N3; $2 = N1; $3 = N2;  // reorder the fields
  print;  // print the whole record
}

      

+4


source


use a loop for

:

{ printf("%s %s %s", $3, $1, $2); 
  for (i = 4; i <= NF; i++) printf("%s ", $i); 
  printf("\n"); 
}

      

+4


source


Perl:

perl -lane '($F[0], $F[2]) = ($F[2], $F[0]); print "@F"' file

      

0


source







All Articles