Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge multiple lines into single line but only for block of lines separated by blank line

Tags:

bash

sh

sed

awk

I am trying to merge multiple lines into single one but with additional conditions.

My input file looks like:

Dm1*(  stuff1 + stuff2 -
stuff3 + stuff4)

+ D1*(D1stuff1 + D1sstuff2 + D1stuff3 + D1stuff4 +
  D1stuff5 - 
  D1stuff6 )

+ D2*(D2stuff)

So there are multiples lines which are also separated by blank lines. All the *stuff* contains long and complicated expressions which also can contain parenthesis.

I want to keep the blank lines as it is but merge the other multiple lines.

The expected output is

Dm1*(  stuff1 + stuff2 - stuff3 + stuff4)

+ D1*(D1stuff1 + D1sstuff2 + D1stuff3 + D1stuff4 + D1stuff5 - D1stuff6 )

+ D2*(D2stuff)

All the current attempts like

awk '{printf("%s",$0)}' 

put everything in a single line. Should I loop over lines or is there any way to identify the blocks between blank lines and apply something into that?

like image 412
Boogeyman Avatar asked Dec 04 '22 18:12

Boogeyman


2 Answers

Even a bit shorter than the version of John1024

awk 'BEGIN { RS=""; ORS="\n\n"}{$1=$1}1'

or

awk -v RS="" -v ORS="\n\n" '{$1=$1}1'

Using RS="" tells awk to use any paragraph as a record (i.e. a block of text separated by blank lines). But it also tells awk that a <newline> is always a field separator in combination with FS. By just redefining the output record separator ORS, we can output everything as you want by telling awk to redefine its record $0 by resetting the first record $1=$1. This has as effect that all field separators defined by FS (the default value here) and the newlines (due to RS="") are replaced by OFS (default a <space;>). Finally we print the record with 1

You can get rid of all the spaces when you additionally set OFS=""

RS The first character of the string value of RS shall be the input record separator; a <newline> by default. If RS contains more than one character, the results are unspecified. If RS is null, then records are separated by sequences consisting of a <newline> plus one or more blank lines, leading or trailing blank lines shall not result in empty records at the beginning or end of the input, and a <newline> shall always be a field separator, no matter what the value of FS is.

source: POSIX awk standard

like image 107
kvantour Avatar answered Dec 27 '22 23:12

kvantour


awk '{if(NF!=0){printf $0}else{printf "\n\n"}}'
like image 37
Cleon Avatar answered Dec 27 '22 23:12

Cleon