6

I need to merge line of a file using sed based on a pattern. eg:

Input File:

X1 A B C D E F

\+ G H I J 1 

\+ LK T PP E OO 2

X2 DDF F Y 

\+ J W Q 

....

OutPut Expected:

X1 A B C D E F G H I J 1 LK T PP E OO 2

X2 DDF F Y J W Q 

..

I would like to equivalent of wat is possible in vi editor (:%s/\n+/ /g)

Searching the web I found a solution, which logically should have worked

sed -e '{:a; N; s/\n+/ /g; ta}' infile

But this command defies my understanding and logic, and has produced output

X1 A B C D E F

\+ G H I J 1 LK T PP E OO 2
X2 DDF F Y 

\+ J W Q 

....

Any ideas are welcome, & Thanks in advance

Srisurya

Jayan
  • 18,003
  • 15
  • 89
  • 143
user1495523
  • 475
  • 2
  • 7
  • 17

3 Answers3

22

This might work for you:

sed ':a;$!N;s/\n+//;ta;P;D' file

explanation:

  • :a is a loop placeholder
  • $!N means if not end-of-file append next line to current line.
  • s/\n+// means delete an end on line followed by a plus sign
  • ta means if last substitution worked branch to a loop placeholder
  • P print upto the first newline.
  • D delete upto and including the first newline.
potong
  • 55,640
  • 6
  • 51
  • 83
  • This saved my bacon. Netstat on Windows puts the process owning the port on a separate line from the connection state information, so I had to do this to get a MOSTLY correct list of established connections: iconv -f utf16le /cygdrive/c/Users/me/netstat-output.txt/System32/test.txt | sed ':a;$!N;s/\r\n \[/ \[/;ta;P;D' | grep ESTABLISHED – Brian Cowan Aug 25 '22 at 17:29
2

an alternative awk oneliner:

awk 'BEGIN{RS="  "}{gsub(/\n\n\+/,"")}1' yourFile
Zombo
  • 1
  • 62
  • 391
  • 407
Kent
  • 189,393
  • 32
  • 233
  • 301
0

potong's answer didn't work for me, but something similar works:

sed -e :a -e '$!N;s/\n+//;ta' -e 'P;D' file

Good sed docs here: http://sed.sourceforge.net/sedfaq3.html

Solubris
  • 3,603
  • 2
  • 22
  • 37