I have played with Powergrep and regular expressions but I don't know how to do that:

I have the text file (source code of webpage) and I want to delete all text (a lot of lines) before the specific string in the code: STRING1 (html tag) and also all the text after another specific string: STRING2. Those strings appears only once in the source code.

  • Please be aware, that regular expressions are generally a terrible tool to parse XML/HTML. – David Foerster Apr 9 '15 at 12:58
  • I agree with David Foerster You can use sed , see stackoverflow.com/questions/3548864/… but I highly advise you run it on a backup first =) – Panther Apr 10 '15 at 1:27

Open a Terminal by pressing Ctrl+Alt+T and use the one of below one linear command. Don't forget to change the input filename to yours.

Using :

awk -v FS="(STRING1|STRING2)" '{print $2}' inputfile > outputfile

Using :

grep -Pzo "(?<=STRING1)(.|\n)*(?=STRING2)" inputfile > outputfile

or with DOTALL (Dot Matches Line Breaks) modifier. It makes . to match even \new line characters.

grep -Pzo "(?s)(?<=STRING1).*?(?=STRING2)" inputfile > outpuffile

The (?s) actives the DOTALL for grep.

or as another alternative to match \new line chars, simply use:

grep -Pzo "(?<=STRING1)[\s\S]*(?=STRING2)" inputfile > outpuffile

In man grep:

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.

-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

-z, --null-data
      Treat the input as a set of lines, each terminated by a zero byte (the ASCII 
      NUL character) instead of a newline. Like the -Z or --null option, this option 
      can be used with commands like sort -z to process arbitrary file names.

(?<=pattern): Known as Positive Lookbehind. A pair of parentheses, with the opening parenthesis followed by a question mark, "less than" symbol, and an equals sign.

So, the (?<=STRING1).*? (positive lookbehind) matches the 0 or more occurrences of any characters(which are optional because of using ? after .*) followed by STRING1 from inputfile.

(?=pattern): Known as Positive Lookahead: The positive lookahead construct is a pair of parentheses, with the opening parenthesis followed by a question mark and an equals sign.

So, the .*?(?=STRING2): (positive lookahead) matches 0 or more occurrences of any characters followed by STRING2.

Links for reading more:
Advanced Grep Topics
GREP for Designers

| improve this answer | |

You can do that with this command:

sed -e '/STRING1/,/STRING2/!d' inputfile > outputfile
| improve this answer | |
  • Thank you, but I don't know where and how to use this command in Powergrep... or where I have to use this command? – Juha Mar 31 '15 at 10:13
  • 1
    In the terminal. – 0x2b3bfa0 Mar 31 '15 at 10:35
  • 2
    This assumes that STRING1 is the only thing on the line. Try sed -e '/.*STRING1/,/STRING2.*/!d' instead. – terdon Mar 31 '15 at 11:57
  • @terdon: Do I update my answer with your improvement quoting you or simply expect that the OP read your comment? – 0x2b3bfa0 Mar 31 '15 at 12:29
  • 3
    Ideally, you include the info from comments in your answer. Comments can be deleted without warning and are easy to miss. However, my comment was wrong. I mean, you are making that assumption but my solution doesn't change that. Try this instead: sed -r 's/.*(STRING1)/\1/;s/(STRING2).*/\1/; /STRING1/,/STRING2/!d' file. – terdon Mar 31 '15 at 12:49

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.