Leo92
Leo92

Reputation: 744

sed from match1 to match2

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

Answers (2)

Florin Stingaciu
Florin Stingaciu

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

Birei
Birei

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

Related Questions