7

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)
αғsнιη
  • 41,407
funfun
  • 99

4 Answers4

17

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)


Bonus ed content:

$ printf '%s\n' 'g/^module/ j' ,p Q | ed -s file
module  x(a,b,c)
module  y(d,e,f,
g,h,i)
module  z(j,k,l)

The above joins any line starting with the string module with its next line.

$ printf '%s\n' 'v/^module/ -,.j' ,p Q | ed -s file
module  x(a,b,c)
module  y(d,e,f,  g,h,i)
module  z(j,k,l)

The above joins any line not starting with the string module with its previous line.

Kusalananda
  • 333,661
4

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.

muru
  • 72,889
1

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
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
0

Using Raku (formerly known as Perl_6)

~$ raku -ne '/^module/ ?? (print "$_\t"; put get) !! .put;'  file

OR:

~$ raku -ne '/^module/ ?? (put join "\t", $_, lines[0]) !! .put;' file  

The Raku answer above is similar to the excellent awk answer by @muru. In Raku the ternary operator is spelled Test ?? True !! False. The -ne flags read the file linewise without autoprinting.

If the line starts with module it is printed, followed by a \t tab (this can be replaced with any column separator). Then (in the first example) the code instructs to get the next line and put it. In the second example you print the $_ topic variable, and take the next line line[0] join on \t and output it. If no match to module (i.e. "False"), the line is simply output.

Sample Input (line-endings cleaned up):

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

Sample Output (tab-separated columns):

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

Note the OP's input text contains trailing whitespace, so while using that raw input may be fine, other example text files that are to be concatenated might not contain trailing whitespace, in which case the "columns" will run-together. Hence the use of \t above to space columns.

https://docs.raku.org
https://raku.org

jubilatious1
  • 3,195
  • 8
  • 17