# Explanation of awk statement

I used this snippet of code to start a new column after every 20th row and each of the columns is separated by tabs. I took the code from this post and then tweaked it a bit: How to start a new column after every nth row?

``````awk '{a[NR%20] = a[NR%20] (NR<=20 ? "" : "\t") \$0} END {for (i = 1; i <= 20; i++) print a[i%20]}'
``````

It does exactly what I want it to do. However, I don't really understand how it works. Can someone please explain it to me? I know that `\$0` will read in the entire record (line) of a file, and that the condition before the question mark is evaluated, and if true, the first statement is executed, and if false, the second is executed. So in this case, if `NR<=20` then nothing is printed because we're on the first column, but if `NR>20` then a tab is printed to start a new column. I also know that the for loop prints out the elements of an array, starting from `a[1%20]` which is `a[1]` and so on, to `a[19%20]` which is `a[19]`, and finally `a[20%20]` which is `a[0]`. But what does `a[NR%20] = a[NR%20]` do? Why is it set equal to itself? I see that when I omit `a[NR%20] = a[NR%20]`, 20 blank lines are printed out.

In `awk`, expressions that are separated by spaces get joined together. This concatenation is described in the POSIX awk manual in a table of expressions (the formatting on that page isn't very clear, it's easier to read via `man 1p awk`). `a[NR%20]` is being joined together with its current value + `""`/`"\t"` + the current record. For the first twenty records, both the array value and the ternary `?:` expression will be empty strings. Brackets might make it more clear:
``````a[NR%n] = (a[NR%n] (NR<=n ? "" : "\t") \$0)
`(NR<=20 ? "" : "\t")` is modifying the second `a[20%20]`, so it is not set equal to itself but gets appended with a tabulation if NR > 20.