Как использовать grep -v, а также исключить следующую строку после совпадения?

Если та метка времени предназначена, чтобы быть временем изменения файла, с GNU находят и xargs, Вы могли сделать:

find f1 -maxdepth 1 -mindepth 1 -printf '%p\0f2/%f_%Td_%Tb_%TH:%TM\0' |
  xargs -r0n2 echo mv

и удалите echo когда счастливый.

14
30.08.2015, 03:16
7 ответов

Вы можете использовать grep с -P (PCRE):

grep -P -A 1 'SomeTest(?!AA)' file.txt

(?! AA) - шаблон отрицательного просмотра вперед нулевой ширины, гарантирующий отсутствие AA после SomeTest .

Тест:

$ grep -P -A 1 'SomeTest(?!AA)' file.txt 
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest
14
27.01.2020, 19:50

Вот решение sed -n , т. Е. Без автоматической печати), которое работает с произвольным вводом:

sed -n '/SomeTestAA/!p          # if line doesn't match, print it
: m                             # label m
//{                             # if line matches
$!{                             # and if it's not the last line
n                               # empty pattern space and read in the next line
b m                             # branch to label m (so n is repeated until a
}                               # line that's read in no longer matches) but
}                               # nothing is printed
' infile

поэтому с вводом вроде

SomeTestAAXX
SomeTestAAYY
+ one line
SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestAABC
+ another line
SomeTestTHREE
EndTest
SomeTestAA
+ yet another line

работает

sed -n -e '/SomeTestAA/!p;: m' -e '//{' -e '$!{' -e 'n;b m' -e '}' -e'}' infile

выводит

SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestTHREE
EndTest

, то есть удаляет именно те строки, которые grep -A1 SomeTestAA infile выберет:

SomeTestAAXX
SomeTestAAYY
+ one line
--
SomeTestAABC
+ another line
--
SomeTestAA
+ yet another line
4
27.01.2020, 19:50

Возможно, вам больше повезет с чем-то, что рассматривает многострочные области как отдельные записи. Есть sgrep , который я мало использовал.

Также есть awk, где вы можете установить разделитель входной записи и разделитель выходной записи по своему усмотрению.

pat="^SomeTestAA"
awk  'BEGIN{ RS=ORS="\nEndTest\n"} !/'"$pat/" foo

Большая часть программы awk заключена в одинарные кавычки, но я использую двойные кавычки в конце, чтобы можно было расширить переменную оболочки $ pat .

3
27.01.2020, 19:50

Один из вариантов - использовать p erl c ompatible r egular e xpression grep :

pcregrep -Mv 'SomeTestAA.*\n' file

Параметр -M позволяет шаблону соответствовать более чем одной строке.

3
27.01.2020, 19:50

Вы можете использовать команду dGNU sedдля удаления строки и префикса /pat/,+Nдля выбора строк, соответствующих шаблону, и последующих N строк. В вашем случае N = 1, так как вы хотите удалить только одну последующую строку после соответствующей строки:

sed -e '/SomeTestAAAA/,+1d'
2
27.01.2020, 19:50

Использование стандартаsed:

$ sed '/SomeTestAA/{ N; d; }' file
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest

Сценарий sedанализирует входной файл построчно, и когда строка соответствует шаблону SomeTestAA, выполняются две sedкоманды редактирования Nи d. Команда Nдобавляет следующую строку ввода в пространство шаблонов (буфер, который sedможет редактировать ), а dудаляет пространство шаблонов и запускает следующий цикл.

2
27.01.2020, 19:50

Пробовал использовать команду Below sed, все работает нормально

команда

sed  '/SomeTestAA/,+1d' filename

выход

SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest
4
27.01.2020, 19:50

Теги

Похожие вопросы