Удалить строки, начинающиеся с шаблона A или B, за исключением случаев, когда они содержат шаблон C или D

Мне больше нравится u2ps , написанный Алексом Суйковым, который создает PDF-файлы гораздо меньшего размера с использованием системных шрифтов Unicode. Этой программы нет в Ubuntu или Fedora; вы должны скомпилировать его самостоятельно. Использование такое же:

$ u2ps text.txt | ps2pdf - text.pdf

(По сравнению с u2ps выход paps огромен ).

0
15.10.2021, 13:35
4 ответа

Рассмотрим данные в файле с именем file. Требования для достижения результатов вашего примера немного отличаются от утверждений, которые вы опубликовали :

.
  • Сохранить все строки в file, соответствующие любому из этих критериев :
    • не начинайте с 1 и2 (это цифра, за которой следует пробел)
    • содержат fooилиbar
  • Удалить все остальные строки
  • Сохраняйте порядок

Это может быть выражено в perlпутем сопоставления двух выражений и печати строки (в последовательности ), если они совпадают:

perl -ne '( !/^(1 |2 )/ or /foo|bar/ ) and print' file

Попутно все это требование можно выразить несколько иначе:

  • Для каждой строки по очереди
    • Печатать строку, если она не начинается с 1 или2
    • Распечатать строку, если она содержит fooилиbar

И это очень удобно сопоставляется с awk:

awk '!/^(1 |2 )/ || /foo/ || /bar/' file

В обоих случаях(perlиawk)RE ^(1 |2 )можно упростить, выделив общий множитель и переписав его как^[12] :

perl -ne '( !/^[12] / or /foo|bar/ ) and print' file
awk '!/^[12] / || /foo/ || /bar/' file
4
15.10.2021, 14:46

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

$ sed '/^[12]\>/ { /foo/ !{ /bar/ !d; }; }' file
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar

В приведенном выше примере sedиспользуется для проверки того, начинается ли каждая строка с 1или 2, за которой следует не -словесный символ (вы можете заменить \>одним пробелом, если хотите ). Если это не так, то печатается строка. Если это так, строка проверяется на наличие подстроки foo. Если эта подстрока существует, строка печатается. Если он не существует, аналогичная проверка выполняется для bar, и строка печатается, если она совпадает, и удаляется, если нет.

Чтение логики из dв обратном порядке :Строка удаляется, если она не соответствует barи не соответствует foo, но начинается с 1или 2.

2
15.10.2021, 15:18

Использование Raku (, ранее известного как Perl _6)

raku -ne '.put if.grep( !/^ [ 1 | 2 ] \s / | / foo | bar / );'  

ИЛИ

raku -ne '.put if.grep( { !/^ [ 1 | 2 ] \s /} | / foo | bar / );'  

ИЛИ

raku -ne '.put if.grep( (none /^ [ 1 | 2 ] \s /) | / foo | bar / );'  

Пример ввода:

1 foo
1 bar
1 someOtherString
2 contains bar and more
2 test
3 contains a random string
4 some other string
2 don't remove this line bar
2 but remove this line
14 keep this line
21 and also this line
7 bar

Пример вывода:

1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar

Выше приведен грубый перевод кода @roaima на Perl5, хотя в Raku это собственно grepоперация. В Raku вы можете проверить отсутствие шаблона, используя показанный выше оператор отрицания !(с/без окружающего кодового блока {...})или используя соединение none(, связанное с Setsв Раку ).

Вы могли заметить включение символа \sв регулярное выражение. Это связано с тем, что необъявленные пробелы(\s)и/или "... пробелы без кавычек в регулярном выражении обычно игнорируются..." по умолчанию в Raku, что делает код более читаемым. См. ссылки ниже.

https://docs.raku.org/language/regexes#Sigspace
https://raku.org

0
18.10.2021, 02:26

Мы можем с пользой использовать обходные пути для такого типа поиска по множеству -условий:

$ grep -vP '^(?=[12]\h)(?!.*(?:foo|bar))' file

Python можно использовать с модулем re для сопоставления и фильтрации на основе статуса результатов поиска.

python3 -c 'import re, sys
with open(sys.argv[1]) as f:
  print(*filter(lambda x: re.match(r"(?![12]\s)",x) or re.search(r"foo|bar",x),f),sep="",end="")
' file
0
19.10.2021, 14:46

Теги

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