11

Let say pattern is string "Love"

input

This is some text
Love this or that
He is running like a rabbit

output

This is some text
Love this or thatHe is running like a rabbit

I've noticed that sed is very unpleasant for deleting newline characters, any idea?

josifoski
  • 1,696
  • 1
  • 14
  • 19
  • 2
    `sed` works on one line at a time. Every time it starts to work on a line it removes the new line and places it on pattern space. Pattern space is where all the action takes place. Once the substitution is done it places the newline and prints to `STDOUT`. To remove new line you need to use `N` which appends the next line to pattern space separated by `\n` which you can then remove with substitution. – jaypal singh Sep 20 '14 at 01:06
  • Do you like space between `that` and `He`? – Jotne Sep 20 '14 at 06:18

5 Answers5

17

You can use this:

sed '/^Love/{N;s/\n//;}' love.txt

details:

/^Love/ identifies the line to treat, if you like you can use /[Ll]ove/ instead

N adds the next line to the pattern space. After this command the pattern space contains Love this or that\nHe is running like a rabbit

s/\n// replaces the newline character

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • only will say wow, it's easy when explained, are { } nececary for using key element N @casimir-et-hippolyte – josifoski Sep 20 '14 at 01:13
  • 1
    @josifoski: curly brackets enclose actions to do when the condition `/^Love/` is true. – Casimir et Hippolyte Sep 20 '14 at 01:15
  • Note that after the first match and replacement, pattern space won't contain a newline before the next line that was pulled in due to the N, and therefore if you had a different pattern to match at the beginning of the next line, it won't be matched. E.g. consider what happens with input file "Love\nLove\nLove". The second Love never gets matched. – Some Guy Dec 15 '20 at 02:58
  • 1
    @SomeGuy: `sed ':a;/[Ll]ove[^\n]*$/{N;ba};s/\n//g' love.txt` solves the problem with a simple loop to append each consecutive matching line before the replacement (global this time). – Casimir et Hippolyte Dec 15 '20 at 22:56
3

Perl:

$ perl -pe 's/^(Love[^\n]*)\n/\1/' file.txt
This is some text
Love this or thatHe is running like a rabbit

Or, if the intent is solely focused on the \n you can chomp based on a pattern:

$ perl -pe 'chomp if /^Love/' file.txt
This is some text
Love this or thatHe is running like a rabbit
dawg
  • 98,345
  • 23
  • 131
  • 206
2
$ awk '/Love/{printf "%s ",$0;next} 1' file
This is some text
Love this or that He is running like a rabbit

Explanation:

  • /Love/{printf "%s ",$0;next}

    For lines that contain Love, the line is printed, via printf, without a newline. awk then starts over on the next line.

  • 1

    For lines that don't include Love, they are printed normally (with a newline). The 1 command is awk's cryptic shorthand for print normally.

John1024
  • 109,961
  • 14
  • 137
  • 171
2

Through Perl,

$ perl -pe 's/^Love.*\K\n//' file
This is some text
Love this or thatHe is running like a rabbit

\K discards previously matched characters.

OR

$ perl -pe '/^Love/ && s/\n//' file
This is some text
Love this or thatHe is running like a rabbit

If a line starts with the string Love, then it removes the newline character from that line.

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
1

Here is another awkvariation:

awk '{ORS=(/Love/?FS:RS)}1' file
This is some text
Love this or that He is running like a rabbi

This change the ORS based on the pattern


Here are some other awk

awk '{printf "%s%s",$0,(/Love/?FS:RS)}' file
This is some text
Love this or that He is running like a rabbit

If line has Love in it use FS as separator, else use RS

This should work too, but use the first one.

awk '{printf "%s"(/Love/?FS:RS),$0}' file
Jotne
  • 40,548
  • 12
  • 51
  • 55
  • If you do not like the space between the two lines, use `awk '{ORS=(/Love/?"":RS)}1'` Even this can be used: `awk 'ORS=(/Love/?FS:RS)'` – Jotne Sep 20 '14 at 06:19