grep инвертированный поиск с контекстом - PullRequest
19 голосов
/ 06 октября 2010

Я хочу отфильтровать несколько строк до и после совпадающей строки в файле.

Это удалит ненужную мне строку:

$ grep -v "line that i don't want"

И это напечатает 2 строки до и после строки, которую я не хочу:

$ grep -C 2 "line that i don't want"

Но когда я объединяю их, она не отфильтровывает 2 строки до и после строки, которую я надеваюне хочу:

# does not remove 2 lines before and after the line I don't want:
$ grep -v -C 2 "line that i don't want"   

Как отфильтровать не только ненужную мне строку, но и строки до и после нее?Я предполагаю, что sed было бы лучше для этого ...

Редактировать: я знаю, что это можно сделать в нескольких строках awk / Perl / Python / Ruby / и т.д., но я хочу знать, еслиесть краткий однострочный текст, который я могу запустить из командной строки.

Ответы [ 5 ]

4 голосов
/ 06 октября 2010

Попробуйте:

sed 'h;:b;$b;N;N;/PATTERN/{N;d};$b;P;D' inputfile

Вы можете изменить количество команд N перед шаблоном, чтобы повлиять на количество удаляемых строк.

Вы можете программно построитьстрока, содержащая количество N команд:

C=2 # corresponds to grep -C
N=N
for ((i = 0; i < C - 1; i++)); do N=$N";N"; done
sed "h;:b;\$b;$N;/PATTERN/{N;d};\$b;P;D" inputfile
2 голосов
/ 18 декабря 2013

Если все строки уникальны, вы можете добавить строки, которые хотите удалить, в файл, а затем использовать этот файл для удаления строк из оригинала, например,

grep -C 2 "line I don't want" < A.txt > B.txt
grep -f B.txt A.txt
1 голос
/ 06 октября 2010
awk 'BEGIN{n=2}{a[++i]=$0}
/dont/{
  for(j=1;j<=i-(n+1);j++)print a[j];
  for(o=1;o<=n;o++)getline;
  delete a}
END{for(i in a)print a[i]} ' file
0 голосов
/ 05 сентября 2016

Я решил это с двумя последовательными grep, на самом деле.Это кажется мне более простым.

grep -C "match" yourfile | grep -v -f - yourfile
0 голосов
/ 12 июня 2015

Я думаю, что у @ fxm27 отличный ответ bash-y.

Я бы добавил, что вы можете решить эту проблему другим способом, используя egrep, если вы заранее знали шаблоны последующих строк.

command | egrep -v "words|from|lines|you|dont|want"

Это будет означать «включающее ИЛИ», означающее, что строка, соответствующая любому из них, будет исключена.

...