4

I've got a file with a bunch of long lines. I'd like to grab every group between two patterns and print them to a new file, one match per line. I could manage to do this with Python, but I'd prefer using just command line tools for this task. If there is no end pattern, I'd like to grab everything 'till the end of the line.

Something like:

input: 
xxSTART relevanttext xxEND something else xxSTART even more relevant

output:
relevanttext
even more relevant
2
  • So START and END both are within the same long line?
    – iruvar
    Sep 26, 2013 at 19:29
  • Yes! I used to have just one match per line, so I'd use sed to grab everything after xxSTART, but now the input data changed and I'm a bit stumped.
    – user48020
    Sep 26, 2013 at 19:30

1 Answer 1

6

IF GNU grep is an option, you could pass the -P (perl-compatible regex) flag and use lookahead assertions, lookbehind assertions and non-greedy matches to pull out what you need

echo 'xxSTART relevanttext xxEND something else xxSTART even more relevant'  |\
grep -oP '(?<=START).*?(?=xxEND|$)'
relevanttext
even more relevant

Or as Stephane Chazelas suggests, use the nifty \K in place of the look-behind assertion

echo 'xxSTART relevanttext xxEND something else xxSTART even more relevant'  |\
grep -oP 'START\K.*?(?=xxEND|$)' 
3
  • 1
    Or: grep -oP 'START\K.*?(?=xxEND|$)' Sep 26, 2013 at 20:27
  • @StephaneChazelas, that's a good point, added in. My version of GNU grep (2.5.1) doesn't support \K though
    – iruvar
    Sep 26, 2013 at 20:35
  • 1
    That's more down to the version of libpcre grep was linked against than the version of grep itself. \K was added in pcre 7.2 (2007) (feature from perl 5.10) Sep 26, 2013 at 20:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.