Reputation: 29
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
Upvotes: 1
Views: 1031
Reputation: 58401
This might work for you (GNU sed):
sed ${lineNumber}'s/[^:]*/'${passwd}'/3' file
Substitute the 3rd occurrence of non-colons with the variable $passwd
on the line numbered $lineNumber
.
Upvotes: 1
Reputation: 1223
You can always use ruby which can do what sed/awk/grep can do and what they cannot do, so you do not have to carry different tools with you. In this example, you can use:
ruby -pe '$_.sub!(/(:[^:]*:)([^:]*)/, "\\1XXX")'
which means to match [a] "a colon, anything not containing a colon, another colon" and [b] "anything not containing a colon", and put back [a] (\\1) and replace [b] with XXX which is supposedly a password.
Upvotes: 0
Reputation: 626802
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.
Upvotes: 2