I'm confused by a portion of the below command.

awk '/<Directory \/>/,/AllowOverride None/{sub("None", "All", $0)}{print}' /etc/apache2/apache2.conf > myfile.txt

The command replaces

<Directory />
    AllowOverride None


<Directory />
    AllowOverride All

in the Apache configuration, and writes the updated configuration to myfile.txt.

I don't understand how the command is pattern matching across two lines of the file. None of the examples that I've been able to find work across lines. I'm guessing it has something to do with the comma in /<Directory /\>,/AllowOverride, but I'd like to understand exactly what's going on. How is this pattern match being done across two lines of the file?

Also, why is {print} necessary? Doesn't awk print its results by default?

  • Good catch. I updated the question. – Ben Rubin Jan 3 '19 at 20:11
  • Address ranges are described here for GNU awk – glenn jackman Jan 3 '19 at 23:51
  • I update my answer with a sample run. – Archemar Jan 4 '19 at 9:58
  • within /<Directory \/>/,/AllowOverride None/ (between those lines)
  • sub( ... ) will substitute None for All
  • a {print} is needed for all lines (substituted or not)

Note that line(s) with AllowOverride None will get a sub and a print, all other line will be printed only.

sample file:

<Directory />
   ## we don't want None
    AllowOverride None
   ## all or None-thing

will become

<Directory />
   ## we don't want All
    AllowOverride All
   ## all or None-thing

about default, consider

... | awk 'NF==7' 

which will by default print lines with 7 fields, however, in your case, sub function overwrite default, so no other action will be taken. That is why you need an explicit print (if you remove explicit print, nothing will be outputed).

| improve this answer | |
  • Well, lines with AllowOverrive None which follow a match for /<Directory \/>/ will get subbed. Since only lines which fall in those ranges will get looked at. – DopeGhoti Jan 3 '19 at 20:08
  • @DopeGhoti The part I don't understand is how the command specifies that AllowOverride None lines that follow <Directory /> lines get substituted. – Ben Rubin Jan 3 '19 at 20:13
  • @Ben Read the answer carefully: . . . lines between / ... /,/ ... / it means first regex is matched -> start of action in first { } braces, second regex is matched -> last line is processed. The second { } braces action takes efect for every lines. – schweik Jan 3 '19 at 20:20
  • 3
    Yes, it's saying for /foo/,/bar/ { stuff } to do stuff between a match for /foo/ and /bar/. – DopeGhoti Jan 3 '19 at 20:37
  • 1
    From the man awk: "A range pattern, expr1,expr2 , matches every record between the match of expr1 and the match expr2 inclusively" () – schweik Jan 3 '19 at 20:38

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.