SED - удалить до 1 и после 2 строк, если совпадают - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть следующие данные

https://link1.com 
asndiaiusdias Rye ioajsidsauihduiashd
link1.com/image.jpg
$89.99


https://link2.com 
8iqiwudhuiqhwdqwuidhuiqhwi Rye iqwdihqwuidhuiqwhduihqwi   
https://link2.com/image.jpg
$22.99


https://link3.com 
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi   
https://link3.com/image.jpg
$42.99



https://link4.com 
iashduhuasdi rye huiqwheui   
https://link4.com/image.jpg
$232.99

Моя цель состоит в том, чтобы в случае чувствительного к регистру совпадения "Rye" (также рожь или RYe или rYe) и удалить 1 строку перед совпадением и 3 строки после матча

, поэтому результат должен быть:

https://link3.com 
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi   
https://link3.com/image.jpg
$42.99

Вы можете использовать sed, grep, awk, не нужно использовать только sed, просто нужно на работу

Ответы [ 5 ]

1 голос
/ 27 февраля 2020

Вы можете использовать это awk с пустым RS:

awk -v RS= '$3 !~ /^[rR][yY][eE]$/' file

https://link3.com
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi
https://link3.com/image.jpg
$42.99
0 голосов
/ 28 февраля 2020

каждый второй ответ предполагает, что 1 строка до и 3 после фактически означает абзацы:

$ perl -00 -ne 'print if !/\Wrye\W/i' input.txt
https://link3.com
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi
https://link3.com/image.jpg
$42.99
  • -00 включает режим абзаца
  • -n не печатается записи по умолчанию
  • 'print if !/\Wrye\W/i - печатает абзац, если он не совпадает с

, однако, если буквально 1 строку до и 3 следует понимать буквально:

$ perl -0777 -pe 's/.*\n.*\Wrye\W.*\n(.*\n){3}//ig' input.txt


https://link3.com
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi
https://link3.com/image.jpg
$42.99
  • -0777 прочитать весь файл
  • -p print
  • .*\n - сопоставить строку, включая конец строки (обратите внимание, что без /s . не соответствует \n)

Примечание: кто-то поднял проблему совместимости с dos в комментарии. "." соответствует любому символу, кроме новой строки, которая включает в себя \r, таким образом, .*\n охватывает также окончания строки DOS.

0 голосов
/ 27 февраля 2020
$ sed -e "/${exclude}/I,+2d" -i /path/to/file

тогда мне легко удалось удалить перед строкой

0 голосов
/ 27 февраля 2020
$ awk -v RS= 'tolower($3) != "rye"' file
https://link3.com
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi
https://link3.com/image.jpg
$42.99

или если вы можете иметь несколько блоков вывода текста и хотите, чтобы каждый из них был разделен пустой строкой:

$ awk -v RS= -v ORS='\n\n' 'tolower($3) != "rye"' file
https://link3.com
8iqiwudhuiqhwdqwuidhuiqhwi SOMETHING ELSE  iqwdihqwuidhuiqwhduihqwi
https://link3.com/image.jpg
$42.99
0 голосов
/ 27 февраля 2020

Кроме того, вы можете использовать Perl для такой работы:

$ perl -i -pe 'BEGIN{undef $/;} s/.*?\n.*rye.*?\n(^.*?\n){3}///mig' input.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...