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, 2021 at 16:40

1 Answer 1


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
    – moth
    Feb 4, 2021 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, 2021 at 11:12
  • ok nice I understand now, thanks.
    – moth
    Feb 4, 2021 at 11:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .