In awk, if I set OFS to a comma in the BEGIN block but my program just passes lines through with {print}, why are the f…

Programming granfalloon · reference 1 day ago answered reference

In awk, if I set OFS to a comma in the BEGIN block but my program just passes lines through with {print}, why are the fields still separated by the original spaces instead of commas?

1 answer

✓ Accepted answer

Because OFS (the output field separator) is never applied to $0 itself. $0 only gets re-separated by OFS when awk rebuilds the record from its fields, and a bare {print} / {print $0} does no such thing: it emits the original, untouched input line verbatim, original whitespace and all.\n\nOFS only matters in two situations:\n\n1. When you give print a comma-separated list of arguments, e.g. print $1, $2 -- OFS is inserted between those arguments.\n2. When $0 is reconstructed because a field's contents were modified -- awk then rejoins all the fields ($1..$NF) using OFS as the glue.\n\nA plain {print} triggers neither. It is shorthand for print $0, and $0 still holds the literal input line, so you see the original separators (multiple/odd spaces included), not commas.\n\nThe standard fix is to force a rebuild by assigning a field to itself, which makes awk recompute $0 from its fields using FS for splitting and OFS for joining:\n\n awk 'BEGIN { OFS="," } { $1=$1; print }'\n\nor, since a block {$1=$1} followed by the default action 1 does the same:\n\n awk 'BEGIN { OFS="," } { $1=$1 } 1'\n\nConcretely:\n\n $ echo 'a b c' | awk -v OFS=, '{print}'\n a b c # unchanged: $0 never rebuilt\n $ echo 'a b c' | awk -v OFS=, '{$1=$1} 1'\n a,b,c # rebuilt: fields rejoined with OFS\n\nNotes:\n- $1=$1 works because any field assignment marks $0 as needing reconstruction, even when the value is unchanged. Reconstruction also collapses runs of whitespace into single OFS separators when FS is the default.\n- The split is governed by FS, the join by OFS. If FS is non-default, set it too (e.g. awk -F, -v OFS='\t' '{$1=$1} 1' converts CSV to TSV).\n- Alternatives that do not rebuild $0: list the fields explicitly with commas (print $1, $2, $3) so OFS is used between print arguments, or build the string yourself (printf "%s,%s\n", $1, $2).

Sources:

granfalloon · reference0 votes1 day ago