Reputation: 744
I have a text , that I want to print what ever between 2 words in that text showing only the first occurrence and disabling greediness if exist for example lets say that I have this text
word1 XXXX
TTTT
YYYY
ZZZZ
GGGG word2 JJJJJJJ word2
ads
word2
adasdas
word1
asadadsasd
word2
what I want is
XXXX
TTTT
YYYY
ZZZZ
GGGG
thanks
Upvotes: 0
Views: 865
Reputation: 8295
So I have a bit of a hack here. But it works.
Test file:
jfkakfakjskfj
**word1** XXXX
TTTT
YYYY
ZZZZ
GGGG **word2**
ads
**word2**
adasdas
**word1**
asadadsasd
**word2**
Output:
**word1** XXXX
TTTT
YYYY
ZZZZ
GGGG **word2**
Sed command:
sed -n '/word1/,$p' file | sed -n '1,/word2/p'
The first sed command matches all the lines from word1
all the way to the end of the file and then we pipe it into the second sed command which matches all the lines from the beginning of the file (which we just piped into it) all the way until word2
is matched. Its tricky but it works.
Upvotes: 1
Reputation: 36272
I would choose perl
for the job.
Assuming infile
with the content of the question and following content of script.pl
:
#!/usr/bin/env perl
use warnings;
use strict;
die qq|Usage: perl $0 <input-file> <word-1> <word-2>\n| unless @ARGV == 3;
my ($word2, $word1) = (pop, pop);
while ( <> ) {
## Remove last '\n'.
chomp;
## Match range between first appearance of 'word1' and first appearance
## of 'word2'.
if ( ( my $w1 = m/\Q$word1/ ) ... ( my $w2 = m/\Q$word2/ ) ) {
## When 'word1' matched remove all characters but spaces until it.
if ( $w1 ) {
s/\A(\s*).*?\Q$word1/$1/;
}
## When 'word2' matched remove all characters after it.
if ( $w2 ) {
s/\A(.*?)\Q$word2\E.*$/$1/;
printf qq|%s\n|, $_;
exit 0;
}
## Print lines inside the range.
printf qq|%s\n|, $_;
}
}
Run it like:
perl script.pl infile word1 word2
With following output:
XXXX
TTTT
YYYY
ZZZZ
GGGG
Upvotes: 1