I'm rearranging the order of the quoted sections.
On Sun, Jan 02, 2022 at 08:14:47PM -0500, The Wanderer wrote:
That's very interesting, although not all that accessible to the
relative newcomer to the field. It does leave me sad about the apparent
conclusion that there is no safe way to edit a file programmatically
(i.e., not via an interactive editor, and possibly not at all) in a way
which preserves the inode; the reasons why I thought of that as
desirable seem less clearly so on further analysis, but it's still
unfortunate for a thing to not be possible to do.
There are several things going on here. I'll address two of them.
First: in order to "preserve the inode", you would need to open the
file in either read+write mode, or clobber+write mode, and then start
overwriting the file once you have the content in memory. This is
inherently dangerous, because if the writing is interrupted before
completion, the file is now corrupted (in the read+write case), or
truncated (in the clobber+write case).
The writing can be interrupted if the process is terminated, or if the
system crashes. Even with uninterruptible power supplies, there's no
100% sure way to prevent a system crash, so there is always a risk.
Second: the idea that a program should be altering (overwriting) the
contents of configuration files *at all* is sketchy. It's a really
bad design. The types of files that people usually want to alter with
sed are designed to be edited by humans. They are *not* amenable to
programmatic alteration, which is why the answers that people come up
with are so contorted.
If you really need to alter a textual configuration file on a bunch of
servers, I suggest editing the file by hand on one machine, making a
diff out of that, and then using patch to apply that diff on all the
other machines. Or use ansible, chef, puppet, etc. This is not a new
or unique problem. Stop reinventing wheels.
A much better approach is what people have started doing with ".d"
directories. Instead of a single monolithic text configuration file
that requires a human brain to comprehend, you put individual pieces
of configuration in separate files. If you want to change the phlogiston
level, you just put the new value in the foobar.d/phlogiston file. No
need for a parser to find the phlogiston variable in a text file.
Of course, the program being configured has to be written to support
such a thing.
unicorn:~$ printf %s\\n foo foo foo | awk '!done && /foo/{$0="bar"; done=1} 1'
bar
foo
foo
I keep forgetting that printf is even a thing in shell, and while awk
did occur to my mind, I don't know it well enough to do anything useful
in it. I can only kind-of parse the syntax you gave there, and that only
because I just saw very similar-looking syntax given for sed in the
Stack Overflow answer linked above.
An awk program consists of a series of alternating conditions and actions.
Each line of input is matched against the conditions, in order. If any
of the conditions matches the input line, then the corresponding action
block is executed.