7

I have 10 fields and I want to start from field 5 to field 10 and ignore the first 5 fields. How can I use NF in awk to do that?

f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10

I want to show only:

f6 f7 f8 f9 f10
c6 c7 c8 c9 c10
2
8

You need to loop through the fields:

bash-4.3$ awk '{for(i=6;i<=NF;i++) printf $i" "; print ""}' input_file.txt 
f6 f7 f8 f9 f10 
c6 c7 c8 c9 c10 

Or you can make fields equal to Null string:

bash-4.3$ awk '{for(i=1;i<=5;i++) $i="";print}' input_file.txt 
     f6 f7 f8 f9 f10
     c6 c7 c8 c9 c10

Or use substring of the whole line , to print all characters from where field 6 begins (credit to https://stackoverflow.com/a/12900372/3701431):

bash-4.3$ awk '{print substr($0,index($0,$6))}' input_file.txt 
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

or simply use cut command:

bash-4.3$ cut -d " " -f6-10  input_file.txt 
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

Python can do that too:

bash-4.3$ python -c 'import sys;fields=[" ".join(line.strip().split()[5:]) for line in sys.stdin];print "\n".join(fields)' < input_file.txt 
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

or alternatively:

$ python -c "import sys;print '\n'.join(map(lambda x:' '.join(x.split()[5:]),sys.stdin.readlines()))" < input_file.txt
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

Or with Ruby:

bash-4.3$ ruby -ne 'print $_.split()[5..10].join(" ");print "\n"' < input_file.txt 
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

Bash + xargs can do it too, although a bit more convoluted:

bash-4.3$ cat input_file.txt | xargs -L 1 bash -c 'arr=($@);for i in $(seq 5 10);do printf "%s " ${arr[$i]} ; done; echo' sh
f6 f7 f8 f9 f10  
c6 c7 c8 c9 c10 
3
  • 1
    I don't think the solution with index() will work if some of the other fields may be equal to or contain $6.
    – Random832
    Dec 22 '16 at 19:58
  • yes, this will work only in this specific case Dec 22 '16 at 20:01
  • printf $i" " will fail when the field has a %.
    – Walter A
    Jun 30 '18 at 10:28
5

Just process the fields of interest. That will be the last field -4, the last field -3, until the actual last field.

Reading from a file with this content (file.txt):

f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10

Run awk on the file as described below. The line with the $ sign is the command. The last two lines are the output.

$ awk '{print $(NF-4)" "$(NF-3)" "$(NF-2)" "$(NF-1)" "$NF}' file.txt
f6 f7 f8 f9 f10
c6 c7 c8 c9 c10

Note: As pointed out by Cyrus in the comment, I removed the bash script and left just the print statement to make it simpler and faster.

2
  • 1
    or awk '{print $(NF-4)" "$(NF-3)" "$(NF-2)" "$(NF-1)" "$NF}' file.txt
    – Cyrus
    Dec 22 '16 at 19:15
  • Thanks ! I'll add the shorter version to the answer. Leaving out the cat pipe. Dec 22 '16 at 19:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.