5

With awk, I can print any column within a CSV, e.g., this will print the 10th column in file.csv.

awk -F, '{ print $10 }' file.csv

If I need to print columns 5-10, including the comma, I only know this way:

awk -F, '{ print $5","$6","$7","$8","$9","$10 }' file.csv

This method is not so good if I want to print many columns. Is there a simpler syntax for printing a range of columns in a CSV in awk?

Village
  • 22,513
  • 46
  • 122
  • 163

3 Answers3

10

The standard way to do this in awk is using a for loop:

awk -v s=5 -v e=10 'BEGIN{FS=OFS=","}{for (i=s; i<=e; ++i) printf "%s%s", $i, (i<e?OFS:ORS)}' file

However, if your delimiter is simple (as in your example), you may prefer to use cut:

cut -d, -f5-10 file

Perl deserves a mention (using -a to enable autosplit mode):

perl -F, -lane '$"=","; print "@F[4..9]"' file
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • 1
    +1 the above `cut` or `awk` is what I'd really do, the `gensub()` answer I posted is just a cute alternative. – Ed Morton Aug 23 '14 at 13:38
5

You can use a loop in awk to print columns from 5 to 10:

awk -F, '{ for (i=5; i<=10; i++) print $i }' file.csv

Keep in mind that using print it will print each columns on a new line. If you want to print them on same line using OFS then use:

awk -F, -v OFS=, '{ for (i=5; i<=10; i++) printf("%s%s", $i, OFS) }' file.csv
anubhava
  • 761,203
  • 64
  • 569
  • 643
3

With GNU awk for gensub():

$ cat file
a,b,c,d,e,f,g,h,i,j,k,l,m
$
$ awk -v s=5 -v n=6 '{ print gensub("(([^,]+,){"s-1"})(([^,]+,){"n-1"}[^,]+).*","\\3","") }' file
e,f,g,h,i,j

s is the start position and n is the number of fields to print from that point on. Or if you prefer to specify start and end:

$ awk -v s=5 -v e=10 '{ print gensub("(([^,]+,){"s-1"})(([^,]+,){"e-s"}[^,]+).*","\\3","") }' file
e,f,g,h,i,j

Note that this will only work with single-character field separators since it relies on being able to negate the FS in a character class.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185