Reputation: 433
Let's consider this simple file:
{
bla bla
bla bla bla
}
{
bla bla
bla bla bla
}
bla bla
bla bla bla
I need to remove only those consecutive lines:
}
{
The result should be:
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
I tried the following:
sed -e '/^}$/,/^{$/d' file
Unfortunately, the last closing curly brace and remaining lines have been removed:
{
bla bla
bla bla bla
bla bla
bla bla bla
Any suggestion?
I'm open to any simple solution involving other tools such as awk/perl/... if necessary.
Upvotes: 1
Views: 286
Reputation: 1126
Also you may use this awk
:
awk 'BEGIN{RS="";FS=OFS="\n"}{print $1,$2,$3,$6,$7,$8,$9,$10}' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
Or using for
loop:
awk 'BEGIN{RS="";FS=OFS="\n"}{
for(i=1;i<=NF;i++) {
if(i == 4 || i == 5) continue; print $i}
}' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
Upvotes: 0
Reputation: 203512
With GNU sed for -z
:
$ sed -z 's/}\n{\n//' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
With GNU awk for multi-char RS:
$ awk -v RS='}\n{\n' -v ORS= '1' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
Upvotes: 2
Reputation:
$ sed '$!N;/^}\n{$/d;P;D' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
This two line buffer will also work for other input as in the following test:
$ cat test
}
}
{
foo
}
$ sed '$!N;/^}\n{$/d;P;D' test
}
foo
}
Upvotes: 1
Reputation: 785146
You may use this sed
:
sed '/^}$/ { N; /\n{$/ d; }' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
To save changes inline:
sed -i.bak '/^}$/ { N; /\n{$/ d; }' file
Alternatively this awk
would also work:
awk '/^}$/ {p = $0; next} p != "" {if (/^{$/) {p=""; next} $0 = p ORS $0; p = ""} 1' file
{
bla bla
bla bla bla
bla bla
bla bla bla
}
bla bla
bla bla bla
Upvotes: 4
Reputation: 241868
Perl solution:
perl -lne 'undef $prev, next if $prev eq "}" && $_ eq "{";
print $prev if defined $prev;
$prev = $_;
END { print $prev if defined $prev}' -- file
-n
reads the input line by line and runs the code for each line.-l
removes newlines from input and adds them to print
.$prev
. If the previous line was }
and the current line is {
, we forget the previous line and read the next line. Otherwise, we print the previous line if there was any (which means we don't print an empty line after the forgotten line). Then we store the current line to $prev and repeat.END
part is needed to print the last remembered line, if any.Upvotes: 3