awk -F, '{print $2}' file.csv pulls out a column in one line, and for machine-generated CSV that's the end of the story. For CSV that came from a spreadsheet, there's a trap that produces wrong numbers instead of errors — so it's worth knowing where the line is.
1. One column
$ clai print the first column of data.csv→ awk -F, '{print $1}' data.csvnameAliceBob
-F, sets the field separator. Fields are $1, $2, … and $0 is the whole line.
2. Several columns, skipping the header
$ clai print columns 1 and 3 from data.csv without the header row→ awk -F, 'NR>1 {print $1, $3}' data.csvAlice 100Bob 250
NR>1 skips line one. NR is the record number, and using it as a condition is how awk does "for the rows where…".
3. Keep it comma-separated on the way out
$ clai extract columns 1 and 3 as valid csv→ awk -F, 'BEGIN{OFS=","} NR>1 {print $1,$3}' data.csvAlice,100Bob,250
print $1, $3 joins with OFS, which defaults to a space. Set it in BEGIN and the output is CSV again.
4. Sum a column
$ clai total up the third column of data.csv→ awk -F, 'NR>1 {s+=$3} END {print "total", s}' data.csvtotal 350
No variable declaration, no initialisation — awk starts numbers at zero. END runs once after the last line.
5. Filter rows, then take a column
$ clai show the names where the amount is over 200→ awk -F, 'NR>1 && $3 > 200 {print $1}' data.csvBob
This is where awk beats a spreadsheet: the same one-liner runs over a 3 GB file without opening it.
6. The trap: a comma inside a quoted field
$ clai print the second column→ awk -F, 'NR>1 {print $2}' data.csvBerlin"Paris
The row Bob,"Paris, France",250 has three logical fields but four commas. Awk doesn't know about quoting, so $2 becomes "Paris, $3 becomes France", and the sum from step 4 silently returns 100 instead of 350. It doesn't error — it just gives you the wrong number.
Gotchas
- Check for quotes before you trust a total.
grep -c '"' file.csv— if that's zero, plain awk is safe. If it isn't, use a real CSV parser:csvcut -c 1,3 data.csv(csvkit),mlr --csv cut -f name,amount(Miller), or three lines of Python. -F,is not-F', '. A separator of comma-plus-space silently produces empty fields on rows without the space.- Windows line endings leave
\ron the last field.$NFcompares unequal for no visible reason. Fix withawk -F, '{gsub(/\r$/,"")} …'or rundos2unixfirst.
Related questions
How do I print the last column? awk -F, '{print $NF}'. NF is the number of fields, so $NF is the last and $(NF-1) the one before it.
How do I use a tab separator? awk -F'\t' — quote it so the shell doesn't eat the backslash.
Is awk faster than pandas for this? For extracting or summing a column from a large file, yes, by a lot — it streams and never builds a data structure. For anything involving joins or reshaping, use pandas.
See also
- Find and replace across every file in a project
- Renaming hundreds of files: from
forloops to plain English - From one-liner to checked-in script: when to graduate
Describe the extraction you want; CliAI writes the awk program, including the BEGIN{OFS=","} you'd forget. Install it in one line.