Reputation: 173
I have a text file file.log contains following text
file.log
ab
cd
ef
I want to replace "ab\ncd" with "ab\n" and the final file.log should look like this:
ab
ef
This is the sed command I am using but it couldn't recognize the newline character to match the pattern:
sed -i 's/\(.*\)\r \(.*\)/\1\r/g' file.log
with 3 character space after '\r' but no change is made with this.
\(.*\)
- This matches any character(.) followed by 0 or more (*) of the preceding character
\r
- For newline
\1
- Substitution for the first matching pattern. In this case, it's 'ab'
Can you help me out what's wrong with the above command.
Upvotes: 1
Views: 171
Reputation: 247250
A couple of other options:
perl -i -0pe 's/^ab\n\Kcd$//mg' file.log
which will change any such pattern in the file
If there's just one, good ol' ed
ed file.log <<END_SCRIPT
/^ab$/+1 c
.
wq
END_SCRIPT
Upvotes: 0
Reputation: 26687
The issue is that, the sed
is a stream editor, which reads line by line from the input file
So when it reads line
ab
from the input file, it doesnt know whether the line is followed by a line
cd
When it reads the line cd
it sed will habe removed the line ab
from the pattern space, this making the pattern invalid for the current pattern space.
Solution
A solution can be to read the entire file, and append them into the hold space, and then replace the hold space. As
$ sed -n '1h; 1!H;${g;s/ab\ncd/ab\n/g;p}' input
ab
ef
What it does
1h
Copies the first line into the hold space.
1!H
All lines excpet the first line (1!
) appends the line to the hold space.
$
matches the last line, performs the commands in {..}
g
copies the contents of hold space back to pattern space
s/ab\ncd/ab\n/g
makes the substitution.
p
Prints the entire patterns space.
Upvotes: 1
Reputation: 174874
Sed processes the input file line by line. So can't do like the above . You need to include N
, so that it would append the next line into pattern space.
$ sed 'N;s~ab\ncd~ab\n~g' file
ab
ef
Upvotes: 1