Using awk to print all columns from the nth to the last
Written by: J Dawg
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.
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}'
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
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"}'
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.
Would this work?
awk '{print substr($0,length($1)+1);}' < file
It leaves some trailing whitespace in front though.
echo "1 2 3 4 5 6" | awk '{ $NF = ""; print $0}'
this one uses awk to print all except the last field
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";
}
Printing out columns starting from #2 (the output will have no trailing space in the beginning):
ls -l | awk '{sub(/[^ ]+ /, ""); print $0}'
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 }'
- 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.
- Where NF defines the total number of fields/columns. Therefore the loop will begin from the 4th field up to the last field/column.
- Where $N retrieves the value of the Nth field. Therefore print $i will print the current field/column based based on the loop count.
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”
Leave a Reply
You must be logged in to post a comment.
[…] 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 […]