Setris
Setris

Reputation: 273

sed — joining a range of selected lines

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.

Upvotes: 8

Views: 1721

Answers (3)

Thor
Thor

Reputation: 47099

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

Upvotes: 2

Steve
Steve

Reputation: 54392

One way using GNU sed:

sed -n '/begin/,/end/ { H;g; s/^\n//; /end/s/\n/ /gp }' file.txt

Upvotes: 6

thb
thb

Reputation: 14434

I like your question. I also like Sed. Regrettably, I do not know how to answer your question in Sed; so, like you, I am watching here for the answer.

Since no Sed answer has yet appeared here, here is how to do it in Perl:

perl -wne 'my $flag = 0; while (<>) { chomp; if (/[begin]/) {$flag = 1;} print if $flag; if (/[end]/) {print "\n" if $flag; $flag = 0;} } print "\n" if $flag;'

Upvotes: 1

Related Questions