Tuesday, October 26, 2021

[SOLVED] How to replace between symbols with sed command in bash

Issue

So I recently asked for help with a sed command for replacing the text between the first and second appearence of a symbol. This is the link to that question: How to replace text in a specific line between first appearence of a symbol and second appearence of it

Now I need something similar, replacing between the second and third appearence, and third to the end of the line

Let's say I have this text file:

aaaa:bbbb:cccc:dddd
eeee:ffff:gggg:hhhh
iiii:jjjj:kkkk:llll
sed "${lineNumber}s/:[^:]*/:${passwd}/" users.txt

What this line does is replacing between first and second ":" in a given line, so the question is how should the command be for replacing between second and third ":", and third to end of the line.

So, for example, the output for replacing between the second and third in the third line with "####" would look like this:

aaaa:bbbb:cccc:dddd
eeee:ffff:gggg:hhhh
iiii:jjjj:kkkk:####

and the code

sed "${lineNumber}s/:[^:]*/:${passwd}/" users.txt
                    ^^^^^^ I think that is what should be replaced

Solution

You can use

sed -E "${lineNumber} s/^(([^:]*:){2})[^:]*/\1${passwd}/"

See the online sed demo:

s='aaaa:bbbb:cccc:dddd
eeee:ffff:gggg:hhhh
iiii:jjjj:kkkk:llll'
passwd='newpass'
lineNumber=2
sed -E "${lineNumber} s/^(([^:]*:){2})[^:]*/\1${passwd}/" <<< "$s"

Output (see the text between the second and third colon on the second line):

aaaa:bbbb:cccc:dddd
eeee:ffff:newpass:hhhh
iiii:jjjj:kkkk:llll

Details

  • ^ - start of string
  • (([^:]*:){2}) - Group 1 (this value is referred to with the \1 placeholder from the regex replacement pattern): two occurrences of any chars other than : and then :
  • [^:]* - zero or more chars other than :.

Note that {2} is a range quantifier that matches its modified pattern a specified amount of times. If you change it to {3}, it will replace after the third occurrence of a : char.



Answered By - Wiktor Stribiżew