1

I'm learning some awk. I found an example online of taking a fixed width file and converting it to a csv file. There is just one part I do not understand, even after going through many man pages and online tutorials:

1: awk -v FIELDWIDTHS='1 10 4 2 2' -v OFS=',' '
2:    { $1=$1 ""; print }
3: ' data.txt`

That is verbatim from the sample online (found here).

What I don't understand is line 2. I get there is no condition, so the 'program' (contained in brackets) will always execute per record (line). I don't understand why it is doing the $1=$1 as well as the empty string statement "";. However, removing these causes incorrect behavior.

ryancdotnet
  • 2,015
  • 16
  • 33
  • 1
    That line can be better written as `{ $1=$1 } 1` and that just forces a change in record structure so that `awk` rewrites each line using `OFS` as comma – anubhava May 24 '17 at 16:19
  • 1
    Thanks @anubhava. When I run `{ $1=$1; print }` it works! Your comment about changing the record structure to cause a rewrite was key! If you want to write an answer, I'll vote it. – ryancdotnet May 24 '17 at 16:25
  • 1
    Also, with that information, I was able to find a relevant SO question with some additional helpful information: https://stackoverflow.com/questions/13704947/print-all-fields-with-awk-separated-by-ofs – ryancdotnet May 24 '17 at 16:25

1 Answers1

1

$1=$1 assigns a value to $1 (just happens to be the same value it already had). Assigning any value to a field cause awk to recompile the current record using the OFS value between fields (effectively replacing all FSs or FIELDSEPS spacings with OFSs).

$ echo 'a,b,c' | awk -F, -v OFS="-" '{print; $1=$1; print}'
a,b,c
a-b-c

The "" is because whoever wrote the script doesn't fully understand awk and thinks that's necessary to ensure numbers retain their precision by converting them to a string before the assignment.

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