SED - delete a line followed by LineFeed (\ n)

I cannot find a suitable sed expression to remove the word followed by the string return (\ n)

Test file:

line1\n line2\n line3mark\n line4\n line5\n 

and I want to delete all label entries \ n, in this case:

 line1\n line2\n line3line4\n line5\n 

searched and can use:

 sed 's/\n//g' test.file to remove ALL \n's 

but

 sed 's/mark\n//g' test.file does not work 

Strange, s / mark \ n // g seems to work fine in vi interactively.

Any help is much appreciated! I would like to understand how to do this using SED, if possible, as I am sure it is possible! However, if this can be done in a different way, I am also happy as long as it is on the command line, since it has to run many files.

Many thanks.

+7
source share
8 answers

For real strings, use:

 sed -e ':a; /mark$/ { N; s/mark\n//; ba; }' 

All lines that end with a character are connected to the next, and now the middle \ n is deleted.

If there is a literal string \n at the end of the line, you need to escape \ like \\n .

+5
source
 sed -i ':a;N;$!ba;s/mark\n//g' file 

Gotta do the trick.

- Page ; (command separator inside sed)
: a (label, as in C / C ++)
N (adds the following line to the pattern space)
$! ba (repeats the N command for all lines except the last line)

- change: more explanation
sed continues like this. it reads standard input into the template space, executes a series of editing commands in the template space, then writes the template space to STDOUT.
When you do something like sed -i 's/mark\n//' file . Strings are copied to the template space one by one.
Here is the first part :a;N;$!ba adds each line to the template space. Then the template space can be processed in one pass, so it’s important to remove any mark\n , g parameter, because it asks sed not to stop at the first matching pattern.

+4
source

I saw the awk tag, so we go.

If \n is a "line feed", awk can join a line ending with a "mark" on the next line.

 $> awk '/mark$/ { sub(/mark$/,""); getline t; print $0 t; next }; 1' ./text line1 line2 line3line4 line5 
+2
source

If you can use awk, you can do

 awk ' /mark$/ {sub(/mark$/, ""); hold = hold $0; next} {print hold $0; hold = ""} END {if (hold) print hold} ' 
+1
source

already many answers, sed and awk.

I add one more, with awk, just show that awk can do this in a shorter command:

 awk 'gsub(/mark$/,""){printf $0;next;}1' input 

Test:

 kent$ echo "line1 line2 line3mark line4 line5"|awk 'gsub(/mark$/,""){printf $0;next;}1' 

exit:

 line1 line2 line3line4 line5 

I don't know if the OP really needs it.

+1
source

Just use the following command

 sed -e "{:q;N;s/mark\n//g;tq}" test.file 
0
source

This might work for you:

 sed -e '1{h;d};H;${x;s/mark\n//g;p};d' test.file 
0
source
 awk '{sub(/line4/,"line3line4")}!/mark/' file line1\n line2\n line3line4\n line5\n 
0
source

All Articles