Paillou
Paillou

Reputation: 839

Remove lines matching a grep pattern

I have several files which I have to remove lines matching a grep pattern and the line before, except for one specific file. I can spot the lines with :

grep -B1 --exclude="my_specific_file.txt" "my_pattern" *_files.txt /dev/null

I'd like to know if it is possible to remove the pattern in all *_files.txt with grep? If there is another option, I'm interested.

Upvotes: 0

Views: 1351

Answers (2)

Shawn
Shawn

Reputation: 52336

A bit of shell and ed:

for file in *_files.txt; do
  if [ "$file" != my_specific_file.txt ]; do
    printf "%s\n" "g/my_pattern/-1,.d" w | ed -s "$file"
  fi
done

Note that ed uses POSIX Basic Regular Expression syntax. The command g/my_pattern/-1,.d will mark every line matching my_pattern and delete them and the preceding lines.

Upvotes: 0

choroba
choroba

Reputation: 241758

Perl to the rescue:

perl -i~ -ne 'BEGIN { $pattern = qr/my_pattern/ }
              if (/$pattern/) { $p = "" }
              else { print $p; $p = $_ }
              print $p if eof && $p !~ /$pattern/;
             ' -- *_files.txt
  • -n reads the input line by line and processes every line by the code specified after -e
  • -i~ replaces each files with the output of the script, keeping the old file as a backup with the ~ suffix
  • we use the variable $p to keep the previous line. If the current line ($_) matches the parent, we clear the previous one, otherwise, we print it and remember the current line.
  • at the end of each file, we print the last line unless it should have been skipped. Without this, the pattern on the very first line would remove the last line of the previously processed file.

Upvotes: 1

Related Questions