Using awk to print all columns from the nth to the last

Written by:

Using awk to print all columns from the nth to the last
  • 0.00 / 5 5
0 votes, 0.00 avg. rating (0% score)

Getting a one-liner awk routine to print the nth field to the last should not be so complicated. For my wish list awk should have a function called ‘fields’ that would perform this tasks. It could have the same syntax as the substr command ie fields(5, 8) which would print fields 5 through 8. Being that I am not aware of built in function like this, you are left with some of the suggestions listed below.

right now I have this line, and it worked until I had whitespace in the second field.

svn status | grep '!' | gawk '{print $2;}' > removedProjs

is there a way to have awk print everything in $2 or greater? ($3, $4.. until we don’t have anymore columns?)

I suppose I should add that I’m doing this in a windows environment with cygwin.

Wim Coenen

will print all but very first column:

cat somefile | awk '{$1=""; print $0}'    

will print all but two first columns:

cat somefile | awk '{$1=$2=""; print $0}'

zed_0xff

There’s a duplicate question with a simpler answer using cut:

 svn status |  grep '!' | cut -d  -f2-

-d specifies the delimeter, -f specifies the list of columns

Joshua Goldberg

You could use a for-loop to loop through printing fields $2 through $NF (built-in variable that represents the number of fields on the line).

Edit:
Since “print” appends a newline, you’ll want to buffer the results:

awk '{out=""; for(i=2;i<=NF;i++){out=$out" "$i}; print $out}'

Alternatively, use printf:

awk '{for(i=2;i<=NF;i++){printf "%s ", $i}; printf "n"}'

Floris

awk '{out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}'

My answer is based on the one of VeeArr, but I noticed it started with a white space before it would print the second column (and the rest). As I only have 1 reputation point, I can’t comment on it, so here it goes as a new answer:

start with “out” as the second column and then add all the other columns (if they exist). This goes well as long as there is a second column.

eugene y

Would this work?

awk '{print substr($0,length($1)+1);}' < file

It leaves some trailing whitespace in front though.

whaley

echo "1 2 3 4 5 6" | awk '{ $NF = ""; print $0}'

this one uses awk to print all except the last field

Birei

This is what I preferred from all the recommendations:

Printing from the 6th to last column.

ls -lthr | awk '{out=$6; for(i=7;i<=NF;i++){out=out" "$i}; print out}'

or

ls -lthr | awk '{ORS=" "; for(i=6;i<=NF;i++) print $i;print "n"}'
@m=`ls -ltr dir | grep ^d | awk '{print $6,$7,$8,$9}'`;
foreach $i (@m)
{
        print "$in";

}

ashish

Printing out columns starting from #2 (the output will have no trailing space in the beginning):

ls -l | awk '{sub(/[^ ]+ /, ""); print $0}'

savvadia

I personally tried all the answers mentioned above, but most of them were a bit complex or just not right. The easiest way to do it from my point of view is:

awk -F" " '{ for (i=4; i<=NF; i++) print $i }'
  1. Where -F” ” defines the delimiter for awk to use. In my case is the whitespace, which is also the default delimiter for awk. This means that -F” ” can be ignored.
  2. Where NF defines the total number of fields/columns. Therefore the loop will begin from the 4th field up to the last field/column.
  3. Where $N retrieves the value of the Nth field. Therefore print $i will print the current field/column based based on the loop count.

Koullis

This was irritating me so much, I sat down and wrote a cut-like field specification parser, tested with GNU Awk 3.1.7.

First, create a new awk library script called pfcut, with e.g.

sudo nano /usr/share/awk/pfcut

Then, paste in the script below, and save. After that, this is how the usage looks like:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-4"); }'
t1 t2 t3 t4

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("2-"); }'
t2 t3 t4 t5 t6 t7

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

To avoid typing all that, I guess the best one can do (see otherwise Automatically load a user function at startup with awk? – Unix & Linux Stack Exchange) is add an alias to ~/.bashrc; e.g. with:

$ echo "alias awk-pfcut='awk -f pfcut --source'" >> ~/.bashrc
$ source ~/.bashrc     # refresh bash aliases

… then you can just call:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk-pfcut '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

Here is the source of the pfcut script:

# pfcut - print fields like cut
#
# sdaau, GNU GPL
# Nov, 2013

function spfcut(formatstring)
{
  # parse format string
  numsplitscomma = split(formatstring, fsa, ",");
  numspecparts = 0;
  split("", parts); # clear/initialize array (for e.g. `tail` piping into `awk`)
  for(i=1;i<=numsplitscomma;i++) {
    commapart=fsa[i];
    numsplitsminus = split(fsa[i], cpa, "-");
    # assume here a range is always just two parts: "a-b"
    # also assume user has already sorted the ranges
    #print numsplitsminus, cpa[1], cpa[2]; # debug
    if(numsplitsminus==2) {
     if ((cpa[1]) == "") cpa[1] = 1;
     if ((cpa[2]) == "") cpa[2] = NF;
     for(j=cpa[1];j<=cpa[2];j++) {
       parts[numspecparts++] = j;
     }
    } else parts[numspecparts++] = commapart;
  }
  n=asort(parts); outs="";
  for(i=1;i<=n;i++) {
    outs = outs sprintf("%s%s", $parts[i], (i==n)?"":OFS); 
    #print(i, parts[i]); # debug
  }
  return outs;
}

function pfcut(formatstring) {
  print spfcut(formatstring);
}

One response to “Using awk to print all columns from the nth to the last”

  1. […] http://objectmix.com/awk/26528-all-c…xcept-one.html http://www.theunixcode.com/2013/12/u…h-to-the-last/ I was trying to point you in the right direction so you could find the answer yourself and learn […]

Leave a Reply