94
votes

I have a problem here. I have to print a column in a text file using awk. However, the columns are not separated by spaces at all, only using a single comma. Looks something like this:

column1,column2,column3,column4,column5,column6

How would I print out 3rd column using awk?

4
Why you would like to use awk? IMHO this is a very simple problem. Do You have any attemt to solve it?TrueY

4 Answers

147
votes

Try:

awk -F',' '{print $3}' myfile.txt

Here in -F you are saying to awk that use , as the field separator.

44
votes

If your only requirement is to print the third field of every line, with each field delimited by a comma, you can use cut:

cut -d, -f3 file
  • -d, sets the delimiter to a comma
  • -f3 specifies that only the third field is to be printed
30
votes

Try this awk

awk -F, '{$0=$3}1' file
column3
  • , Divide fields by ,
  • $0=$3 Set the line to only field 3
  • 1 Print all out. (explained here)

This could also be used:

awk -F, '{print $3}' file
3
votes

A simple, although -less solution in :

while IFS=, read -r a a a b; do echo "$a"; done <inputfile

It works faster for small files (<100 lines) then as it uses less resources (avoids calling the expensive fork and execve system calls).

EDIT from Ed Morton (sorry for hi-jacking the answer, I don't know if there's a better way to address this):

To put to rest the myth that shell will run faster than awk for small files:

$ wc -l file
99 file

$ time while IFS=, read -r a a a b; do echo "$a"; done <file >/dev/null

real    0m0.016s
user    0m0.000s
sys     0m0.015s

$ time awk -F, '{print $3}' file >/dev/null

real    0m0.016s
user    0m0.000s
sys     0m0.015s

I expect if you get a REALY small enough file then you will see the shell script run in a fraction of a blink of an eye faster than the awk script but who cares?

And if you don't believe that it's harder to write robust shell scripts than awk scripts, look at this bug in the shell script you posted:

$ cat file
a,b,-e,d
$ cut -d, -f3 file
-e
$ awk -F, '{print $3}' file
-e
$ while IFS=, read -r a a a b; do echo "$a"; done <file

$