Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.debian.user > #243589 > unrolled thread

Replace line in file based on pattern

Started by"Paul M. Foster" <paulf@quillandmouse.com>
First post2022-01-03 00:10 +0100
Last post2022-01-03 07:50 +0100
Articles 15 — 7 participants

Back to article view | Back to linux.debian.user


Contents

  Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 00:10 +0100
    Re: Replace line in file based on pattern Andy Smith <andy@strugglers.net> - 2022-01-03 00:20 +0100
      Re: Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 03:00 +0100
    Re: Replace line in file based on pattern The Wanderer <wanderer@fastmail.fm> - 2022-01-03 00:30 +0100
      Re: Replace line in file based on pattern Greg Wooledge <greg@wooledge.org> - 2022-01-03 00:50 +0100
        Re: Replace line in file based on pattern The Wanderer <wanderer@fastmail.fm> - 2022-01-03 02:20 +0100
          Re: Replace line in file based on pattern Greg Wooledge <greg@wooledge.org> - 2022-01-03 02:50 +0100
            Re: Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 03:30 +0100
              Re: Replace line in file based on pattern Andrei POPESCU <andreimpopescu@gmail.com> - 2022-01-15 13:40 +0100
        Re: Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 04:00 +0100
          Re: Replace line in file based on pattern Greg Wooledge <greg@wooledge.org> - 2022-01-03 05:10 +0100
            Re: Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 14:40 +0100
              Re: Replace line in file based on pattern David Wright <deblis@lionunicorn.co.uk> - 2022-01-04 20:50 +0100
      Re: Replace line in file based on pattern "Paul M. Foster" <paulf@quillandmouse.com> - 2022-01-03 03:00 +0100
        Re: Replace line in file based on pattern john doe <johndoe65534@mail.com> - 2022-01-03 07:50 +0100

#243589 — Replace line in file based on pattern

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 00:10 +0100
SubjectReplace line in file based on pattern
Message-ID<DBi9c-Mv-5@gated-at.bofh.it>
Folks:

In a script, I'd like to search for a pattern in a file, and replace 
that line entirely with a new line, once (not globally). I've tried

sed -i s/search/new_line/

but this only replaces the string itself. I want the script to find the 
line my search term is on, and replace the whole line with my 
replacement line.

Anyone know how to do this?

Paul

[toc] | [next] | [standalone]


#243590

FromAndy Smith <andy@strugglers.net>
Date2022-01-03 00:20 +0100
Message-ID<DBiiS-PG-13@gated-at.bofh.it>
In reply to#243589
Hello,

On Sun, Jan 02, 2022 at 05:52:36PM -0500, Paul M. Foster wrote:
> In a script, I'd like to search for a pattern in a file, and replace that
> line entirely with a new line, once (not globally). I've tried
> 
> sed -i s/search/new_line/
> 
> but this only replaces the string itself. I want the script to find the line
> my search term is on, and replace the whole line with my replacement line.

Match the whole line, not just the string.

sed -i 's/^.*search.*$/new line/' filename

The ^ and $ anchor at start and end respectively and the .* matches
everything.

You can instead use sed's 'c' modifier to tell it to replace the
whole line:

sed -i '/search/new line/c' filename

but I personally prefer to give exact matches.

Cheers,
Andy

-- 
https://bitfolk.com/ -- No-nonsense VPS hosting

[toc] | [prev] | [next] | [standalone]


#243599

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 03:00 +0100
Message-ID<DBkNI-26v-11@gated-at.bofh.it>
In reply to#243590
On 1/2/22 6:18 PM, Andy Smith wrote:
> Hello,
> 
> On Sun, Jan 02, 2022 at 05:52:36PM -0500, Paul M. Foster wrote:
>> In a script, I'd like to search for a pattern in a file, and replace that
>> line entirely with a new line, once (not globally). I've tried
>>
>> sed -i s/search/new_line/
>>
>> but this only replaces the string itself. I want the script to find the line
>> my search term is on, and replace the whole line with my replacement line.
> 
> Match the whole line, not just the string.
> 
> sed -i 's/^.*search.*$/new line/' filename

This works. I'm not that familiar with regexps, so this didn't occur to 
me in the first place.

> 
> The ^ and $ anchor at start and end respectively and the .* matches
> everything.
> 
> You can instead use sed's 'c' modifier to tell it to replace the
> whole line:
> 
> sed -i '/search/new line/c' filename

This did not work, at least the way you've written it here. I can't say 
why, but it did not make any changes to the file in question.

Paul

[toc] | [prev] | [next] | [standalone]


#243591

FromThe Wanderer <wanderer@fastmail.fm>
Date2022-01-03 00:30 +0100
Message-ID<DBisy-SG-3@gated-at.bofh.it>
In reply to#243589

[Multipart message — attachments visible in raw view] — view raw

On 2022-01-02 at 17:52, Paul M. Foster wrote:

> Folks:
> 
> In a script, I'd like to search for a pattern in a file, and replace
> that line entirely with a new line, once (not globally). I've tried

What do you mean by "globally"?

If you mean that you want to only replace the first matching line in the
file, but leave any subsequent matching lines alone... I've never
actually had occasion to do that, but a bit of Googling (for 'sed first
match only') found me

https://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file

which looks like at least the seed of a way to do it; see also below.

> sed -i s/search/new_line/
> 
> but this only replaces the string itself. I want the script to find the 
> line my search term is on, and replace the whole line with my 
> replacement line.
> 
> Anyone know how to do this?

Without re-testing at the moment, I'd say from past experience that you
want:

sed -i 's/^.*search.*$/new_line/'

This matches the beginning of the line, followed by zero or more
characters, followed by the search string, followed by zero or more
characters, followed by the end of the line.

Whether or not the quotes are necessary depends on what your 'search'
and 'new_line' strings consist of, but I habitually include them just to
be on the safe side.

There may well be ways to do this more readily using other tools, but I
don't know them off the top of my head, and that should be the way to do
it using sed.


Combining this with the suggestion from the link above would produce
something like:

sed -i '0,/^.*search.*$/{s/^.*search.*$/new_line/}'

I have *not* tested that, since I don't have a suitable test input file
ready to hand and don't feel like throwing one together right at the
moment, but it looks like it should produce the desired result.

-- 
   The Wanderer

The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all
progress depends on the unreasonable man.         -- George Bernard Shaw

[toc] | [prev] | [next] | [standalone]


#243593

FromGreg Wooledge <greg@wooledge.org>
Date2022-01-03 00:50 +0100
Message-ID<DBiLU-Z6-3@gated-at.bofh.it>
In reply to#243591
On Sun, Jan 02, 2022 at 06:20:15PM -0500, The Wanderer wrote:
> If you mean that you want to only replace the first matching line in the
> file, but leave any subsequent matching lines alone... I've never
> actually had occasion to do that, but a bit of Googling (for 'sed first
> match only') found me
> 
> https://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file
> 
> which looks like at least the seed of a way to do it; see also below.

Why does everyone think sed is an appropriate tool for this?  It's
some sort of malevolent meme, I swear.

unicorn:~$ printf %s\\n foo foo foo | awk '!done && /foo/{$0="bar"; done=1} 1'
bar
foo
foo

Of course, given the ORIGINAL question, the best tool is neither of these.
It's something like ansible or puppet.  Or if you insist on jury-rigging
crap together with stone knives and bearskins, ssh and patch.

See also <http://backreference.org/2011/01/29/in-place-editing-of-files/>.

[toc] | [prev] | [next] | [standalone]


#243594

FromThe Wanderer <wanderer@fastmail.fm>
Date2022-01-03 02:20 +0100
Message-ID<DBkb0-1TJ-9@gated-at.bofh.it>
In reply to#243593

[Multipart message — attachments visible in raw view] — view raw

On 2022-01-02 at 18:40, Greg Wooledge wrote:

> On Sun, Jan 02, 2022 at 06:20:15PM -0500, The Wanderer wrote:
> 
>> If you mean that you want to only replace the first matching line
>> in the file, but leave any subsequent matching lines alone... I've
>> never actually had occasion to do that, but a bit of Googling (for
>> 'sed first match only') found me
>> 
>> https://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file
>>
>>  which looks like at least the seed of a way to do it; see also
>> below.
> 
> Why does everyone think sed is an appropriate tool for this?  It's 
> some sort of malevolent meme, I swear.

Probably, at least in part, because it's the tool that can potentially
do it which people are already most familiar with based on having
encountered / used it elsewhere.

In this specific case, I stuck with it not only because of that but also
because it was the tool the original inquirer was already using.

> 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.

> Of course, given the ORIGINAL question, the best tool is neither of
> these. It's something like ansible or puppet.  Or if you insist on
> jury-rigging crap together with stone knives and bearskins, ssh and
> patch.

I'm not sure what original question you're referring to; I infer that
it's probably going to be something that predates this thread, because
the one that opened this thread doesn't seem to have any nexus to either
of that first pair of tools.

I can kind of see how patch (and, if applicable for working with things
on a remote machine, ssh) could be used for something like this, but
only in limited contexts. For the biggest issue, AFAIK and AFAICT patch
is line-based, and I infer from the post which started this thread
(specifically the fact that the search pattern does not consist of the
entire line) that the full line which needs to be replaced is not known.

If patch provides any facility which would let it be usable in that
case, I'm not seeing it. (Unless maybe you provide the patch in the form
of an ed script? I don't know whether ed has the breadth of features to
make this doable either, but it seems likely. I didn't even remember
that ed scripts were valid patch format until rereading the man page
just now.)

> See also
> <http://backreference.org/2011/01/29/in-place-editing-of-files/>.

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.

-- 
   The Wanderer

The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all
progress depends on the unreasonable man.         -- George Bernard Shaw

[toc] | [prev] | [next] | [standalone]


#243596

FromGreg Wooledge <greg@wooledge.org>
Date2022-01-03 02:50 +0100
Message-ID<DBkE1-239-1@gated-at.bofh.it>
In reply to#243594
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.

In my example, there are two condition/action pairs:

1) Condition: !done && /foo/
   Action: {$0="bar"; done=1}

2) Condition: 1 (always true)
   Action: omitted, so the default action of "print" is used.

The second pair could be written out more explicitly, but I used the
extremely condensed form.

So, what this does is look for lines containing the regex "foo", which is
equivalent to simply matching the substring "foo".  If such a line is found,
and if the "done" variable is NOT set to a nonzero value, then we change
the whole input line to "bar", and then set the done variable to 1.  This
prevents the condition from triggering a second time.

The second condition matches every line, so that we always print something.
Either we print "bar" (if the first action was triggered), or else we
print a copy of the original input line.

All together, what this does is "the first time we match foo, print bar
instead; otherwise copy the input line", which is what was requested.

[toc] | [prev] | [next] | [standalone]


#243601

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 03:30 +0100
Message-ID<DBlgJ-2vQ-3@gated-at.bofh.it>
In reply to#243596
On 1/2/22 8:46 PM, Greg Wooledge wrote:
> 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.

Altering a config file programmatically is exactly what ansible does, 
and the functionality desired in the original post is one of the things 
ansible has a module for.

I have no idea how ansible handles interruptions.

> 
> 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.

I'm not interested in hacking a bunch of servers. Just one. The whole 
purpose here is to restore a system to more or less its original 
configuration when a reinstall must occur. A reinstall must occur when 
there is a severe hardware failure, or when Debian (or any other 
operating system) comes up with a major revision (in Debian's case, 
every couple of years). The problem I've seen with just copying an old 
config file over the top of the one installed by default is that in some 
cases, syntax changes or options are added or deleted in the config 
files from one version to another. Thus, my idea of "surgical" 
alteration of the config files.

Ansible supposedly will do this, but in certain circumstances, I've been 
unable to make it work on a remote machine. I can't say why. However, it 
occurred to me that ssh, rsync and bash/basic tools can accomplish the 
same goals.

You mentioned diff and patch earlier, and these might well be good 
tools. The problem is that I'm relatively unfamiliar with patch and 
diff. I know how they work, but I'm inexpert in their use.

> 
> 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.

I absolutely abhor the *.d solution. Most software that I'm aware of is 
built to read a single config file. For example, exim. Personally, I 
find it vastly easier to load a single config file in an editor and 
search for a value, than to grep through a bunch of files and load the 
one which has the value I seek. My personal preference.

> 

> 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.

Awk is another tool I'm only vaguely familiar with. I'm much more 
familiar with sed and grep. If I had your expertise, I might look at it 
differently.

Paul

[toc] | [prev] | [next] | [standalone]


#244006

FromAndrei POPESCU <andreimpopescu@gmail.com>
Date2022-01-15 13:40 +0100
Message-ID<DFQvD-4Ri-7@gated-at.bofh.it>
In reply to#243601

[Multipart message — attachments visible in raw view] — view raw

On Du, 02 ian 22, 21:22:33, Paul M. Foster wrote:
> 
> I'm not interested in hacking a bunch of servers. Just one. The whole
> purpose here is to restore a system to more or less its original
> configuration when a reinstall must occur. A reinstall must occur when there
> is a severe hardware failure, or when Debian (or any other operating system)
> comes up with a major revision (in Debian's case, every couple of years).
> The problem I've seen with just copying an old config file over the top of
> the one installed by default is that in some cases, syntax changes or
> options are added or deleted in the config files from one version to
> another. Thus, my idea of "surgical" alteration of the config files.

If I understand correctly you mean:

1. System is installed with package foo version 1.0

2. You customize configuration of package foo

3. At some point in the future a reinstall might be required and you 
want to restore the system to the state at point 2.

If you are still on the same stable release a simple overwrite of the 
configuration should do it as, by definition, stable shouldn't introduce 
major changes (like syntax changes in the configuration file[1]).

If you want to reinstall the system with a newer release of Debian you 
are probably better of just going through each and every changed 
configuration file with something like vimdiff[2].


There are at least two reasons to this:

A. As you already noted above, configuration file syntax may change.

Any automated method you can think of involves a risk of doing a change 
that will simply be wrong for the newer version. While examining the 
situation to tell whether it's safe to do automatically or not you might 
as well just do the change manually.

Tools like vimdiff make it very easy to apply changes selectively.


B. On (typically major) upgrades a package might consider your 
customizations and adapt accordingly, however installing a fresh new 
version might not.

This is because both upstreams and Debian are doing their best to enable 
in-place upgrades whenever possible, even between major releases. Such 
mechanisms typically involve having the old configuration already in 
place, either during the upgrade (if done by package scripts) or at 
first start of the new software version (if done by the software 
itself).

While it may work if you make sure you replace / edit / whatever the 
configuration before the first start of the software it can't possibly 
work if the changes are managed via package scripts (for hopefully 
obvious reasons).


[1] exceptions to this rule might happen, e.g. if the change of 
configuration (syntax) is required to fix a security issue or in cases 
where fixing security issues is done by upgrading to newer major 
versions of the software (as for Firefox, Chrome, etc.).

[2] going through the Release Notes and NEWS.Debian first is highly 
recommended, as these are the places where the need for manual changes 
are documented.

Hope this helps,
Andrei
-- 
http://wiki.debian.org/FAQsFromDebianUser

[toc] | [prev] | [next] | [standalone]


#243603

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 04:00 +0100
Message-ID<DBlJL-2Fl-1@gated-at.bofh.it>
In reply to#243593
On 1/2/22 6:40 PM, Greg Wooledge wrote:
> On Sun, Jan 02, 2022 at 06:20:15PM -0500, The Wanderer wrote:

> Of course, given the ORIGINAL question, the best tool is neither of these.
> It's something like ansible or puppet.  Or if you insist on jury-rigging
> crap together with stone knives and bearskins, ssh and patch.
> 

Regarding "patch", let's consider a "stock" config file from a fresh 
install (call it NEW), and an existing config which is tweaked for my 
purposes (call it OLD). Assume I want the stock config altered to 
conform to my existing/working installation.

To make patch work, I need a diff file, which I get from diffing OLD and 
NEW. From there, I use patch and the diff to bring NEW to conform to 
OLD, more or less.

Once I've gone through this whole evolution, how is this process 
different from simply copying OLD over the top of NEW? Bear in mind that 
we aren't working with C files here, but config files, where changes are 
minimal and possibly confined to a small area.

I'm not being sarcastic or argumentative. I'm genuinely trying to 
understand how patch would be a real/superior solution.

Paul

[toc] | [prev] | [next] | [standalone]


#243615

FromGreg Wooledge <greg@wooledge.org>
Date2022-01-03 05:10 +0100
Message-ID<DBmPv-3CQ-1@gated-at.bofh.it>
In reply to#243603
On Sun, Jan 02, 2022 at 09:59:08PM -0500, Paul M. Foster wrote:
> Regarding "patch", let's consider a "stock" config file from a fresh install
> (call it NEW), and an existing config which is tweaked for my purposes (call
> it OLD). Assume I want the stock config altered to conform to my
> existing/working installation.

If you're reinstalling after a disk or system failure, you should be
able to drop the config files from your backup onto the system, either
before or after you install the software packages that use those files.

The scenario you seem to be imagining involves reinstalling software
packages and somehow ending up with a *different* version of the software
than you had been running on the failed system.  This isn't going
to happen if you were running Debian stable, and you reinstall Debian
stable.

The only way it would be a concern is if you're *not* running Debian
stable, or if you reinstall with something other than Debian stable.
In those cases, well, you're kinda on your own.

> To make patch work, I need a diff file, which I get from diffing OLD and
> NEW. From there, I use patch and the diff to bring NEW to conform to OLD,
> more or less.

I proposed patch because I was imagning a scenario in which you're
administering multiple systems, and you want to make the same change to
the same file on a bunch of systems, BUT the file in question isn't
identical across all systems.  Maybe it's got a hostname or an IP address
or something in it, and therefore you are supposed to "edit" the file
with a text editor, find the right line, find the right column, and make
your changes by hand, with immediate visual feedback to tell you that
it looks "right".

As long as the change you're making isn't within a couple lines of the
varying part, the resulting diff should apply cleanly to all your
systems.

patch is also viable for the "stupid Docker user" case that we see all
the time on IRC.  In this scenario, the user (I can't even call them an
administrator) has some pre-made Docker image, and they want to
install it repeatedly on the same (virtual) machine, over and over, but
this image hasn't been fully customized for their machine.  So they
want to make changes to it after they install it.  The same changes.
Every.  Single.  Time.

(I have no idea why these people don't just make their change to the
image that they're installing from.)  (I also have no idea whey they're
installing the same image multiple times.  I suspect it's got something
to do with setting up a pristine build environment...?)

Anyway, for that scenario, a diff file applied by patch is safer than
whatever atrocity they write using GNU sed.  Then again, for that
scenario, they could also just drop whole files onto the system, rather
than trying to "edit" the image's stock files.  Yet they don't seem
to consider either of these solutions.  Nope.  It's always "how 2 sed??".

[toc] | [prev] | [next] | [standalone]


#243629

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 14:40 +0100
Message-ID<DBvJ8-u8-13@gated-at.bofh.it>
In reply to#243615
On 1/2/22 11:03 PM, Greg Wooledge wrote:
> On Sun, Jan 02, 2022 at 09:59:08PM -0500, Paul M. Foster wrote:
>> Regarding "patch", let's consider a "stock" config file from a fresh install
>> (call it NEW), and an existing config which is tweaked for my purposes (call
>> it OLD). Assume I want the stock config altered to conform to my
>> existing/working installation.
> 
> If you're reinstalling after a disk or system failure, you should be
> able to drop the config files from your backup onto the system, either
> before or after you install the software packages that use those files.

This is a fair point. In the case of a hardware failure, simply 
reinstalling working configs over the top of "stock" ones would work fine.

> 
> The scenario you seem to be imagining involves reinstalling software
> packages and somehow ending up with a *different* version of the software
> than you had been running on the failed system.  This isn't going
> to happen if you were running Debian stable, and you reinstall Debian
> stable.
> 
> The only way it would be a concern is if you're *not* running Debian
> stable, or if you reinstall with something other than Debian stable.
> In those cases, well, you're kinda on your own.

I am running stable. Where this situation arises is when I've been 
running for a couple of years and Debian changes to a new version (10 to 
11, for example). By that time, I have a lot of cruft on the machine, 
and I've just found it best to reinstall. And I've had it happen where a 
package changes its config, and I have to manually figure out what 
they've done, and how to compensate for it, to get back to a "working" 
(for me) state.

There are a lot of folks who like to "fiddle" with their systems 
constantly. I don't. So I'm not keen on having to manually fiddle with a 
lot of configs after an O/S version change.

Paul

[toc] | [prev] | [next] | [standalone]


#243697

FromDavid Wright <deblis@lionunicorn.co.uk>
Date2022-01-04 20:50 +0100
Message-ID<DBXYJ-U6-3@gated-at.bofh.it>
In reply to#243629
On Mon 03 Jan 2022 at 08:38:32 (-0500), Paul M. Foster wrote:
> On 1/2/22 11:03 PM, Greg Wooledge wrote:
> > On Sun, Jan 02, 2022 at 09:59:08PM -0500, Paul M. Foster wrote:
> > > Regarding "patch", let's consider a "stock" config file from a fresh install
> > > (call it NEW), and an existing config which is tweaked for my purposes (call
> > > it OLD). Assume I want the stock config altered to conform to my
> > > existing/working installation.
> > 
> > If you're reinstalling after a disk or system failure, you should be
> > able to drop the config files from your backup onto the system, either
> > before or after you install the software packages that use those files.
> 
> This is a fair point. In the case of a hardware failure, simply
> reinstalling working configs over the top of "stock" ones would work
> fine.

I use a little scheme to backup the configuration files that I change.
I copy them into a directory /home/system-<hostname>-<debiancodename>-<fslabel>
changing / into ¬ so that the files are all in the one directory.
It makes restoration easy, and also things like comparing systems
with one another, and archival of how I configured things long ago
(the directories remain small enough to keep for good).

Obviously one needs something like this when you don't backup the
entire system but only the information you "own", ie /home and perhaps
/root and bits of /var.

> > The scenario you seem to be imagining involves reinstalling software
> > packages and somehow ending up with a *different* version of the software
> > than you had been running on the failed system.  This isn't going
> > to happen if you were running Debian stable, and you reinstall Debian
> > stable.
> > 
> > The only way it would be a concern is if you're *not* running Debian
> > stable, or if you reinstall with something other than Debian stable.
> > In those cases, well, you're kinda on your own.
> 
> I am running stable. Where this situation arises is when I've been
> running for a couple of years and Debian changes to a new version (10
> to 11, for example). By that time, I have a lot of cruft on the
> machine, and I've just found it best to reinstall. And I've had it
> happen where a package changes its config, and I have to manually
> figure out what they've done, and how to compensate for it, to get
> back to a "working" (for me) state.
> 
> There are a lot of folks who like to "fiddle" with their systems
> constantly. I don't. So I'm not keen on having to manually fiddle with
> a lot of configs after an O/S version change.

Cheers,
David.

[toc] | [prev] | [next] | [standalone]


#243597

From"Paul M. Foster" <paulf@quillandmouse.com>
Date2022-01-03 03:00 +0100
Message-ID<DBkNI-26v-7@gated-at.bofh.it>
In reply to#243591
On 1/2/22 6:20 PM, The Wanderer wrote:
> On 2022-01-02 at 17:52, Paul M. Foster wrote:
> 
>> Folks:
>>
>> In a script, I'd like to search for a pattern in a file, and replace
>> that line entirely with a new line, once (not globally). I've tried
> 
> What do you mean by "globally"?

"Globally" just means I want to replace the first instance, rather than 
appending the 'g' modifier to the sed expression.

> 
> If you mean that you want to only replace the first matching line in the
> file, but leave any subsequent matching lines alone... I've never
> actually had occasion to do that, but a bit of Googling (for 'sed first
> match only') found me
> 
> https://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file
> 
> which looks like at least the seed of a way to do it; see also below.
> 
>> sed -i s/search/new_line/
>>
>> but this only replaces the string itself. I want the script to find the
>> line my search term is on, and replace the whole line with my
>> replacement line.
>>
>> Anyone know how to do this?
> 
> Without re-testing at the moment, I'd say from past experience that you
> want:
> 
> sed -i 's/^.*search.*$/new_line/'
> 
> This matches the beginning of the line, followed by zero or more
> characters, followed by the search string, followed by zero or more
> characters, followed by the end of the line.

This works, as I mentioned in another reply. The context here is a file 
which would have something like: ';extension=gd', to be replaced by 
'extension=gd'. That is, I want to programmatically uncomment a line, in 
most cases.

Paul

[toc] | [prev] | [next] | [standalone]


#243621

Fromjohn doe <johndoe65534@mail.com>
Date2022-01-03 07:50 +0100
Message-ID<DBpkl-548-1@gated-at.bofh.it>
In reply to#243597
On 1/3/2022 2:56 AM, Paul M. Foster wrote:
> On 1/2/22 6:20 PM, The Wanderer wrote:
>> On 2022-01-02 at 17:52, Paul M. Foster wrote:
>>
>>> Folks:
>>>
>>> In a script, I'd like to search for a pattern in a file, and replace
>>> that line entirely with a new line, once (not globally). I've tried
>>
>> What do you mean by "globally"?
>
> "Globally" just means I want to replace the first instance, rather than
> appending the 'g' modifier to the sed expression.
>
>>
>> If you mean that you want to only replace the first matching line in the
>> file, but leave any subsequent matching lines alone... I've never
>> actually had occasion to do that, but a bit of Googling (for 'sed first
>> match only') found me
>>
>> https://stackoverflow.com/questions/148451/how-to-use-sed-to-replace-only-the-first-occurrence-in-a-file
>>
>>
>> which looks like at least the seed of a way to do it; see also below.
>>
>>> sed -i s/search/new_line/
>>>
>>> but this only replaces the string itself. I want the script to find the
>>> line my search term is on, and replace the whole line with my
>>> replacement line.
>>>
>>> Anyone know how to do this?
>>
>> Without re-testing at the moment, I'd say from past experience that you
>> want:
>>
>> sed -i 's/^.*search.*$/new_line/'
>>
>> This matches the beginning of the line, followed by zero or more
>> characters, followed by the search string, followed by zero or more
>> characters, followed by the end of the line.
>
> This works, as I mentioned in another reply. The context here is a file
> which would have something like: ';extension=gd', to be replaced by
> 'extension=gd'. That is, I want to programmatically uncomment a line, in
> most cases.

In addition to the other answers:

In the below cmds '/^# extension=md/' will only modify the line matching
that specific pattern, the first cmd will only replace '# ' while the
second will answer your original question.

$ printf "%s\n" extention=md '# extension=md' '#extension=md' | sed '/^#
extension=md/s/# //'

$ printf "%s\n" extention=md '# extension=md' '#extension=md' | sed '/^#
extension=md/s/^# extension=md.*/extension=md/'


Note that this e-mail is folded by my mailer.

--
John Doe

[toc] | [prev] | [standalone]


Back to top | Article view | linux.debian.user


csiph-web