Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed — joining a range of selected lines

Tags:

sed

I'm a beginner to sed. I know that it's possible to apply a command (or a set of commands) to a certain range of lines like so

sed '/[begin]/,/[end]/ [some command]'

where [begin] is a regular expression that designates the beginning line of the range and [end] is a regular expression that designates the ending line of the range (but is included in the range).

I'm trying to use this to specify a range of lines in a file and join them all into one line. Here's my best try, which didn't work:

sed '/[begin]/,/[end]/ {
N
s/\n//
}
'

I'm able to select the set of lines I want without any problem, but I just can't seem to merge them all into one line. If anyone could point me in the right direction, I would be really grateful.

like image 241
Setris Avatar asked Sep 24 '12 03:09

Setris


2 Answers

One way using GNU sed:

sed -n '/begin/,/end/ { H;g; s/^\n//; /end/s/\n/ /gp }' file.txt
like image 147
Steve Avatar answered Sep 28 '22 02:09

Steve


This is straight forward if you want to select some lines and join them. Use Steve's answer or my pipe-to-tr alternative:

sed -n '/begin/,/end/p' | tr -d '\n'

It becomes a bit trickier if you want to keep the other lines as well. Here is how I would do it (with GNU sed):

join.sed

/\[begin\]/ {
  :a
  /\[end\]/! { N; ba }
  s/\n/ /g
}

So the logic here is:

  1. When [begin] line is encountered start collecting lines into pattern space with a loop.
  2. When [end] is found stop collecting and join the lines.

Example:

seq 9 | sed -e '3s/^/[begin]\n/' -e '6s/$/\n[end]/' | sed -f join.sed

Output:

1
2
[begin] 3 4 5 6 [end]
7
8
9
like image 21
Thor Avatar answered Sep 28 '22 00:09

Thor