Linux grep, как я могу отобразить строки, которые не содержат слово 1 и слово 2, но все еще отображают строки, в которых есть оба слова - PullRequest
0 голосов
/ 03 апреля 2020

Мне нужна помощь с отображением всех строк, которые не содержат word1 или word2, но должны отображаться строки, содержащие оба из них.

Пример:

aaaa bbbb cccc
bbbb bbbb bbbb
cccc cccc cccc
dddd dddd aaaa

если word1 = aaaa и word2 = bbbb, тогда вывод должен быть:

aaaa bbbb cccc
cccc cccc cccc

Tried

grep -Ewv "word1/word2" file.txt 

, но это показывает только строки, которые их не содержат, это не так покажите строки, содержащие

Мне нужно сделать это с помощью команды grep, забыл упомянуть об этом

Ответы [ 3 ]

1 голос
/ 03 апреля 2020

Grep версии обоих или ни одного из них:

grep -v -P '((?=.*aaaa)(?!.*bbbb))|((?=.*bbbb)(?!.*aaaa))'

Но, пожалуйста, не используйте grep в этом случае. Отрицательный и позитивный взгляд в будущее может легко привести к Катастрофе c Возврат

GNU grep знает Perl совместимый синтаксис регулярного выражения (PCRE) (опция -P). Эта вещь все еще называется «регулярным» выражением, хотя оно больше не является регулярным. Другие люди более откровенны и вызывают обратный вызов нерегулярных выражений.

Как это работает:

(?=.*aaaa) соответствует aaaa в любом месте строки, но не перемещает курсор. После совпадения следующий поиск начинается в начале строки.

(?!.*bbbb) совпадает, если в строке нет bbbb и курсор также не перемещается.

Оба совпадения совпадают строки, которые включают aaaa, но не включают bbbb.

Это один из случаев, который вы хотите исключить из результатов поиска. Второе после условия или (|) - это другое, которое вы хотите исключить: любое bbbb без aaaa.

. Выше вы определили, что вам не нужно. Затем используйте -v, чтобы инвертировать поиск, чтобы получить то, что вы хотите.

intended output

0 голосов
/ 04 апреля 2020

На мой взгляд, самый простой способ (хотя, возможно, и не самый быстрый) состоит в том, чтобы отдельно найти строки, которые не содержат ни слова, и строки, содержащие оба слова, и объединить результаты. Например (при условии, что file.txt представляет собой текстовый файл в каталоге test, и я передаю входные значения в качестве переменных среды для общности - и мы ищем только полные слова, а не фрагменты слов):

[mathguy@localhost test]$ more file.txt
aaaa bbbb cccc
bbbb bbbb bbbb
cccc cccc cccc
dddd dddd aaaa



[mathguy@localhost test]$ word1=aaaa
[mathguy@localhost test]$ word2=bbbb

[mathguy@localhost test]$ ( grep "\b$word1\b" file.txt | grep "\b$word2\b" ; \
>  grep -v "\b$word1\b" file.txt | grep -v "\b$word2\b" ) | cat
aaaa bbbb cccc
cccc cccc cccc
0 голосов
/ 03 апреля 2020

Bash версия обоих или ни одного из них:

#! /bin/bash

word1=${1:-aaaa}
word2=${2:-bbbb}

while read -r line; do
  if [[ $line =~ $word1 ]]; then
    if [[ $line =~ $word2 ]]; then
      printf "%s\n" "$line"
    fi
  else
    if [[ $line =~ $word2 ]]; then
      :
    else
      printf "%s\n" "$line"
    fi
  fi
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...