Grep инвертировать поиск с контекстом
Я хочу отфильтровать несколько строк до и после соответствующей строки в файле.
Это приведет к удалению строки, которую я не хочу:
$ grep -v "line that i don't want"
И это напечатает две строки до и после строки, которую я не хочу:
$ 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/etc, но я хочу знать, есть ли один лайнер, который можно выполнить из командной строки.
Ответы
Ответ 1
Попробуйте:
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
Если строки уникальны, вы можете grep строки, которые хотите удалить в файл, а затем использовать этот файл для удаления строк из оригинала, например
grep -C 2 "line I don't want" < A.txt > B.txt
grep -f B.txt A.txt
Ответ 3
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
Ответ 4
Я думаю, что @fxm27 имеет отличный ответ bash -y.
Я бы добавил, что вы могли бы решить этот другой способ, используя egrep, если бы заранее знали шаблоны последующих строк.
command | egrep -v "words|from|lines|you|dont|want"
Это сделает "включительно ИЛИ", что означает, что строка, соответствующая любому из них, будет исключена.
Ответ 5
Я решил это с двумя последовательными grep, на самом деле. Для меня это кажется более простым.
grep -C "match" yourfile | grep -v -f - yourfile