Strip comments and blank lines from a config
Problem statement
You want to diff the effective settings of two nginx configs, so all the comments and empty lines have to go. Remove full-line comments (including indented ones), inline comments at the end of a line together with the spaces before them, and every line that is blank or becomes blank. Keep indentation of the remaining lines.
nginx.conf
# upstream settingsupstream api { server 10.0.0.11:8080; # primary server 10.0.0.12:8080; # server 10.0.0.13:8080; (retired)} # timeoutsproxy_read_timeout 60s;Examples
Example 1
Input: Run the command on `nginx.conf`.
Output: upstream api {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
proxy_read_timeout 60s;
Hints
Approach
Two expressions run in order on each line. The first, s/[[:space:]]*#.*$//, deletes a #, everything after it, and any whitespace just before it. On a full-line comment that leaves the line empty or whitespace-only. On server 10.0.0.11:8080; # primary it trims the inline comment. The second, /^[[:space:]]*$/d, deletes any line that is now empty or only whitespace, covering both the original blank lines and the lines emptied by step one. Because the deletion happens after the substitution, one pass handles everything.
sed -e 's/[[:space:]]*#.*$//' -e '/^[[:space:]]*$/d' nginx.confFollow-up questions
- How would you use this to diff two configs in one command? (
diff <(sed ... a.conf) <(sed ... b.conf)) - How would you print only the lines between
upstream api {and}?
Frequently asked questions
No. A # can be part of a value, such as a URL fragment, a quoted string or a colour code. For config formats where that happens, only strip # that starts a line or follows whitespace (s/[[:space:]]+#.*$// with -E), or use a parser for the format.