0

I am trying to do something like this:

sed -i.bak '/^startswith/ s/$/endswith/' /path/to/file

But only for lines that do not already end with the string "endswith".

In words, I want to find lines that start with some text and that do not end with some other text and then append my desired text at the end of that line.

I am currently referring to Search and replace a substring only if another substring is not present and the sed man page, but I am not sure if I'm on the right track.

1
  • If you provide concise, testable sample input/output then we could test potential solutions before posting them.
    – Ed Morton
    Oct 17, 2021 at 23:28

4 Answers 4

2

The following approach works:

sed -i.bak '/endswith/b; /^startswith/ s/$/endswith/' /path/to/file

I'm not sure if it is the most efficient solution, however.

2
  • 1
    I think that's not bad at all; it will probably run more or less as fast as the equivalent alternatives /endswith$/!{/^startswith/s/$/endswith/;} and /endswith$/!s/^startswith.*/&endswith/.
    – Quasímodo
    Oct 16, 2021 at 21:53
  • @Quasímodo - thank you. If you wish to add your solution with a good explanation as an answer, I'll accept it.
    – MountainX
    Oct 17, 2021 at 0:06
1

If I understood you correctly:

sed '/^startswith/s/endswith$//; /^startswith/s/$/endswith/' /path/to/file

From the left to the right:
/^startswith - find all lines that start with 'startswith',
s/endswith$// - basically remove trailing/suffix 'endswith',
/^startswith - find me again all lines that start with 'startswith',
s/$/endswith/ - at this point all '^startswith' lines are without 'endswith' at the end, so just add it.

1
  • Thank you. Looks a bit inefficient, but I learned from it.
    – MountainX
    Oct 17, 2021 at 17:14
0

Just use awk:

awk '/^startswith/{ sub(/(endswith)?$/,"endswith") } 1' /path/to/file
0

Using Raku (formerly known as Perl_6)

raku -pe 's/ (^^ header \s .* $$) /$0 trailer/ unless /trailer $$/;'  

Sample Input:

header 0123456789
header 0123456789 trailer
none   0123456789 trailer
none   0123456789

Sample Output:

header 0123456789 trailer
header 0123456789 trailer
none   0123456789 trailer
none   0123456789

https://docs.raku.org/syntax/s$SOLIDUS$SOLIDUS$SOLIDUS
https://raku.org

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.