Consider the file test.txt:


Now consider the following awk command and its output:

awk '(NR>1) {print "s/"p"/"$1"/g"}{p=$1}' test.txt


NR>1 is true for lines greater than one, this is valid for the "$1" term but not for "p" which takes the value of the first line. Why is that? Does NR>1 evaluate just the first block {} and not the second {p=$1}? Why does the first "$1" have double quotes "" while second $1 does not?

  • someone is apparently using an awk script to generate a sed script - that's not necessary since awk can do the substitutions directly itself and generally a bad idea as it's hard to do robustly. – Ed Morton Feb 4 at 16:40

you (splited) awk command looks like

awk '(NR>1) {print "s/"p"/"$1"/g"}

which means

  • do {print "s/"p"/"$1"/g"} when NR>1
  • do {p=$1} always
  • "s/"p"/"$1"/g" quote splits (1): "s/" + p + "/" + $1 + "/g" , neither p nor $1 are quoted
  • (1) + for concatenation, note that awk use space (no space) as implicit concatenation operator

on first line, only {p=$1} is executed.

on second line {print "s/"p"/"$1"/g"} is executed first, and value of p is initialized from first line.

on last line, p end up with pfg039G that is discarded.

Use a semicolon in the same code block in order to create a series of commands:

awk '(NR>1) {print "s/"p"/"$1"/g" ; p=$1}' test.txt

Now the result is as expected using $1 from the previous match - in the first line, $1 is empty.

  • what about the use of double quotes and no quotes on "$1" $1 – alex Feb 4 at 11:09
  • @alex The double quotes are not around $1 but around / and /g. I would have written the statement as printf "s/%s/%s/g\n", p, $1. – Kusalananda Feb 4 at 11:12
  • ok nice I understand now, thanks. – alex Feb 4 at 11:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.