1

I can't find this case in the board, so I'm asking the question.

This is input file:

module  
x(a,b,c)  
module  
y(d,e,f,  
g,h,i)  
module  
z(j,k,l)

And output file should be:

module x(a,b,c)  
module y(d,e,f,  
g,h,i)  
module z(j,k,l)
  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you! – Jeff Schaller Jan 20 '19 at 13:01
4

What you want to do is to join the module lines with the next line.

Using sed:

$ sed '/^module/N;s/\n//' file
module  x(a,b,c)
module  y(d,e,f,
g,h,i)
module  z(j,k,l)

This is with your data copied and pasted as is, with spaces at the end of each line.

The sed command will print each line as it is read, but when it encounters a line that starts with the string module, it appends the next line with an embedded newline character in-between (this is what N does). We remove that newline character with a substitution before the result is printed.

If your data has no spaces at the end of the lines, use

$ sed '/^module/N;s/\n/ /' file
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)

Just in case you'd want this (assuming no spaces at end of input lines):

$ sed -e '/^module/bpp' -e 'H;$bpp' -e 'd' \
      -e ':pp' -e 'x;/^$/d;s/\n/ /g' file
module x(a,b,c)
module y(d,e,f, g,h,i)
module z(j,k,l)

Annotated sed script:

/^module/ b print_previous; # print previous record
H;                          # append this line to hold space
$         b print_previous; # print previous (last) record
d;                          # end processing this line

:print_previous;            # prints a record accumulated in the hold space
x;                          # swap in the hold space
/^$/ d;                     # if line is empty, delete it
s/\n/ /g;                   # replace embedded newlines by spaces
                            # (implicit print)
| improve this answer | |
1

Using awk:

~ awk '/^module/ {l = $0; getline; printf "%s", l} 1' input-file
module  x(a,b,c)
module  y(d,e,f,
g,h,i)
module  z(j,k,l)

For each line that starts with module, save the line in l, move to the next line (getline), and print the saved line without a newline. Then print every line.

| improve this answer | |
0

Another option: create an ed script!

This starts by pre-counting the number of joins that are required; it then generates that number of ed search & join commands and pipes them, along with a save & quit at the end, into ed:

#!/bin/bash
n=$(grep -c '^module *$' input)
{
  for((i=1; i <= n; i++))
  do
    printf '/^module *$/\n.,+1j\n'
  done
  echo w
  echo q
} | ed -s input >/dev/null
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.