Я столкнулся с этим в 2017 году с Linux Mint 18.1 (Serena ), поэтому я думаю, что это заслуживает обновленного ответа. Эта проблема была зарегистрирована как Github issue #1429 и как ошибка Launchpad#1592293 .
Исправление появилось вместе с этой фиксацией , которая была помечена как версия 3.4.2 Nemo, так что это должна быть выпущенная версия, исправляющая проблему.
Решение этой проблемы состоит в том, чтобы просто получить обновленную версию Nemo. Обновление до последней версии Linux Mint (18.2 )должно быть достаточным; однако в примечаниях к выпуску не указано, какая именно версия Nemo включена.
awk '$0 !~/Fine|Doing/' i.txt
выход
Hi
Its Been Long Time
Чтобы удалить все строки, содержащие слова Doing
или Fine
, вы можете использовать grep
следующим образом:
grep -Fw -v -e 'Doing' -e 'Fine' file
Опция -F
заставляет grep
использовать заданные выражения как строки , а не как регулярные выражения, а -w
заставляет сопоставлять целые слова (, а не подстроки других слов, например Doings
или Fines
). Опция -v
инвертирует смысл теста, так что строки, соответствующие заданным выражениям, удаляются из вывода. Две строки задаются с помощью -e
, который используется для получения выражения для запроса с помощью (. Этот параметр часто опускается, но здесь он необходим, поскольку у нас их два ).
С помощью sed
можно сделать
sed -e '/\<Doing\>/d' -e '/\<Fine\>/d' file
или
sed '/\<Doing\>/d; /\<Fine\>/d' file
или
sed -E '/\<(Doing|Fine)\>/d' file
Каждый из них соответствует двум строкам как словам. Специальные шаблоны \<
и \>
соответствуют пробелу нулевой ширины -в начале и конце слова соответственно (пробелу между символом слова -и символом, отличным от -слова -). В GNU sed
вы можете использовать \b
вместо \<
и \>
.
Последняя команда sed
использует чередование для соответствия любому слову. Чередование — это функция расширенных регулярных выражений, поэтому мы включаем их с помощью -E
в командной строке.
Во всех случаях шаблон сопоставляется с каждой строкой ввода, и если он совпадает, он удаляется с помощью команды d
. Все остальные строки печатаются.
Обратное, вывод всех строк, которые не совпадают, и игнорирование остальных, может быть выполнено с помощью
sed -n -E '/\<(Doing|Fine)\>/!p' file
То есть отключите вывод данных по умолчанию с помощью -n
и затем печатайте(p
)только те строки, которые не соответствуют(!
)шаблону.
Код awk
будет выглядеть очень похожим на код sed
с использованием расширенных регулярных выражений,по крайней мере, при использовании GNU awk
(, который понимает \<
и\>
):
awk '!/\<(Doing|Fine)\>/' file
или
awk '!/\<Doing\>/ && !/\<Fine\>/' file
Они оба пытаются сопоставить два слова с входными данными и не будут печатать данные, если слова присутствуют.
Вы также можете использовать функцию index()
в awk
, но это также будет находить слова как подстроки (, точно так же, как с помощью /(Doing|Fine)/
):
awk '!index($0, "Doing") && !index($0, "Fine")' file
index($0, string)
возвращает ноль, если string
не найдено в$0
(всей строке ), поэтому отрицание результата с помощью !
даст вам истинное значение, если строка не была нашел.
Длинный -способ сделать это в awk
— проверить каждое поле отдельно:
awk '{ for (i = 1; i <= NF; ++i) if ($i == "Doing" || $i == "Fine") next; print }' file
Это проверяет каждое поле на наличие двух слов и сразу же переходит к следующей строке ввода, если одно из них найдено. В противном случае строка печатается.
Это дало бы результаты, отличные от использования /\<(Doing|Fine)\>/
, если бы в тексте присутствовало такое слово, как A-Doing
. Цикл не заметит его (, потому что поля разделены пробелами ), но регулярное выражение заметит (, потому что -
не является -символом слова -).