Printing the nth range with sed

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I can print the braceted lines in the file a
first
[
third
fourth
]
sixth
[
eighth
]
tenth
by doing
% <a sed -n '/[/,/]/p'
which prints
[
third
fourth
]
[
eighth
]
But what if I want only the second match, ie. the last three lines?
text-processing sed
add a comment |Â
up vote
1
down vote
favorite
I can print the braceted lines in the file a
first
[
third
fourth
]
sixth
[
eighth
]
tenth
by doing
% <a sed -n '/[/,/]/p'
which prints
[
third
fourth
]
[
eighth
]
But what if I want only the second match, ie. the last three lines?
text-processing sed
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I can print the braceted lines in the file a
first
[
third
fourth
]
sixth
[
eighth
]
tenth
by doing
% <a sed -n '/[/,/]/p'
which prints
[
third
fourth
]
[
eighth
]
But what if I want only the second match, ie. the last three lines?
text-processing sed
I can print the braceted lines in the file a
first
[
third
fourth
]
sixth
[
eighth
]
tenth
by doing
% <a sed -n '/[/,/]/p'
which prints
[
third
fourth
]
[
eighth
]
But what if I want only the second match, ie. the last three lines?
text-processing sed
asked yesterday
Toothrot
739416
739416
add a comment |Â
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
0
down vote
Easier to do with awk, assuming the blocks defined by [ and ] do not themselves contain [ or ] inside the block
$ awk -v b=2 '/[/c++ c==b; /]/ && c==bexit' ip.txt
[
eighth
]
-v b=2variable to specify which block is required/[/c++increment counter if line matches starting conditionc==b;print input record if counter is equal to block required/]/ && c==bexitexit on matching ending condition
another way to write this:
awk -v b=2 '/[/c++ c==bprint $0; if(/]/) exit' ip.txt
add a comment |Â
up vote
0
down vote
$ sed -n '/^[/h; /^[/,/^]/H; $x;s/^[n//;p;' file
[
eighth
]
Annotated sed script (assumes -n):
/^[/h; # replace hold space with this line
/^[/,/^]/H; # append these lines to hold space with embedded newlines
$ # at last line of input
x; # swap in the hold space
s/^[n//; # delete the first "[" and the newline following it
p; # print
That is, whenever we find a line that starts with [, clear the hold space by copying the line there. Then keep appending lines to the hold space until we find the corresponding line that starts with ].
At the end, we will have a hold space with one [ too many, so delete that (and the embedded newline after it) before printing the data.
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
add a comment |Â
up vote
0
down vote
Using sed editor, we can perform it as follows:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/n2$//p ;# only when counter had 2 chars in it, we print block
/n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/n/;x ;# target block not reached, so increment
' input.file
with Perl, we can use the ... operator in tandem with the boolean $k == 2, indicating that we have reached the intended target block and need to print it.
perl -lne 'print if /^[/ && ++$k == 2 ... /^]/' input.file
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Easier to do with awk, assuming the blocks defined by [ and ] do not themselves contain [ or ] inside the block
$ awk -v b=2 '/[/c++ c==b; /]/ && c==bexit' ip.txt
[
eighth
]
-v b=2variable to specify which block is required/[/c++increment counter if line matches starting conditionc==b;print input record if counter is equal to block required/]/ && c==bexitexit on matching ending condition
another way to write this:
awk -v b=2 '/[/c++ c==bprint $0; if(/]/) exit' ip.txt
add a comment |Â
up vote
0
down vote
Easier to do with awk, assuming the blocks defined by [ and ] do not themselves contain [ or ] inside the block
$ awk -v b=2 '/[/c++ c==b; /]/ && c==bexit' ip.txt
[
eighth
]
-v b=2variable to specify which block is required/[/c++increment counter if line matches starting conditionc==b;print input record if counter is equal to block required/]/ && c==bexitexit on matching ending condition
another way to write this:
awk -v b=2 '/[/c++ c==bprint $0; if(/]/) exit' ip.txt
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Easier to do with awk, assuming the blocks defined by [ and ] do not themselves contain [ or ] inside the block
$ awk -v b=2 '/[/c++ c==b; /]/ && c==bexit' ip.txt
[
eighth
]
-v b=2variable to specify which block is required/[/c++increment counter if line matches starting conditionc==b;print input record if counter is equal to block required/]/ && c==bexitexit on matching ending condition
another way to write this:
awk -v b=2 '/[/c++ c==bprint $0; if(/]/) exit' ip.txt
Easier to do with awk, assuming the blocks defined by [ and ] do not themselves contain [ or ] inside the block
$ awk -v b=2 '/[/c++ c==b; /]/ && c==bexit' ip.txt
[
eighth
]
-v b=2variable to specify which block is required/[/c++increment counter if line matches starting conditionc==b;print input record if counter is equal to block required/]/ && c==bexitexit on matching ending condition
another way to write this:
awk -v b=2 '/[/c++ c==bprint $0; if(/]/) exit' ip.txt
edited yesterday
answered yesterday
Sundeep
6,9411725
6,9411725
add a comment |Â
add a comment |Â
up vote
0
down vote
$ sed -n '/^[/h; /^[/,/^]/H; $x;s/^[n//;p;' file
[
eighth
]
Annotated sed script (assumes -n):
/^[/h; # replace hold space with this line
/^[/,/^]/H; # append these lines to hold space with embedded newlines
$ # at last line of input
x; # swap in the hold space
s/^[n//; # delete the first "[" and the newline following it
p; # print
That is, whenever we find a line that starts with [, clear the hold space by copying the line there. Then keep appending lines to the hold space until we find the corresponding line that starts with ].
At the end, we will have a hold space with one [ too many, so delete that (and the embedded newline after it) before printing the data.
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
add a comment |Â
up vote
0
down vote
$ sed -n '/^[/h; /^[/,/^]/H; $x;s/^[n//;p;' file
[
eighth
]
Annotated sed script (assumes -n):
/^[/h; # replace hold space with this line
/^[/,/^]/H; # append these lines to hold space with embedded newlines
$ # at last line of input
x; # swap in the hold space
s/^[n//; # delete the first "[" and the newline following it
p; # print
That is, whenever we find a line that starts with [, clear the hold space by copying the line there. Then keep appending lines to the hold space until we find the corresponding line that starts with ].
At the end, we will have a hold space with one [ too many, so delete that (and the embedded newline after it) before printing the data.
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
add a comment |Â
up vote
0
down vote
up vote
0
down vote
$ sed -n '/^[/h; /^[/,/^]/H; $x;s/^[n//;p;' file
[
eighth
]
Annotated sed script (assumes -n):
/^[/h; # replace hold space with this line
/^[/,/^]/H; # append these lines to hold space with embedded newlines
$ # at last line of input
x; # swap in the hold space
s/^[n//; # delete the first "[" and the newline following it
p; # print
That is, whenever we find a line that starts with [, clear the hold space by copying the line there. Then keep appending lines to the hold space until we find the corresponding line that starts with ].
At the end, we will have a hold space with one [ too many, so delete that (and the embedded newline after it) before printing the data.
$ sed -n '/^[/h; /^[/,/^]/H; $x;s/^[n//;p;' file
[
eighth
]
Annotated sed script (assumes -n):
/^[/h; # replace hold space with this line
/^[/,/^]/H; # append these lines to hold space with embedded newlines
$ # at last line of input
x; # swap in the hold space
s/^[n//; # delete the first "[" and the newline following it
p; # print
That is, whenever we find a line that starts with [, clear the hold space by copying the line there. Then keep appending lines to the hold space until we find the corresponding line that starts with ].
At the end, we will have a hold space with one [ too many, so delete that (and the embedded newline after it) before printing the data.
answered yesterday
Kusalananda
100k13199311
100k13199311
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
add a comment |Â
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
This will print the last block and not the second. In this dataset, the second block happens to be the last is why it seems to work.
â Rakesh Sharma
yesterday
add a comment |Â
up vote
0
down vote
Using sed editor, we can perform it as follows:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/n2$//p ;# only when counter had 2 chars in it, we print block
/n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/n/;x ;# target block not reached, so increment
' input.file
with Perl, we can use the ... operator in tandem with the boolean $k == 2, indicating that we have reached the intended target block and need to print it.
perl -lne 'print if /^[/ && ++$k == 2 ... /^]/' input.file
add a comment |Â
up vote
0
down vote
Using sed editor, we can perform it as follows:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/n2$//p ;# only when counter had 2 chars in it, we print block
/n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/n/;x ;# target block not reached, so increment
' input.file
with Perl, we can use the ... operator in tandem with the boolean $k == 2, indicating that we have reached the intended target block and need to print it.
perl -lne 'print if /^[/ && ++$k == 2 ... /^]/' input.file
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Using sed editor, we can perform it as follows:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/n2$//p ;# only when counter had 2 chars in it, we print block
/n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/n/;x ;# target block not reached, so increment
' input.file
with Perl, we can use the ... operator in tandem with the boolean $k == 2, indicating that we have reached the intended target block and need to print it.
perl -lne 'print if /^[/ && ++$k == 2 ... /^]/' input.file
Using sed editor, we can perform it as follows:
sed -ne ' ;# "-n" suppresses autoprint of pattern space
/^[/!d ;# skip lines that donot begin a fresh block
:a;$!N;/n]/!ba ;# keep appending lines to pattern space until end of block
G ;# append our makeshift counter (hold space) to pattern spc
s/n2$//p ;# only when counter had 2 chars in it, we print block
/n$/!q ;# target block, 2nd block has been printed so quit
x;s/$/n/;x ;# target block not reached, so increment
' input.file
with Perl, we can use the ... operator in tandem with the boolean $k == 2, indicating that we have reached the intended target block and need to print it.
perl -lne 'print if /^[/ && ++$k == 2 ... /^]/' input.file
answered yesterday
Rakesh Sharma
3033
3033
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460627%2fprinting-the-nth-range-with-sed%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password