Подтвердить что ты не робот

Команда Unix для отображения файлов, содержащих строку, но * NOT *, содержащих другую строку

Как я рекурсивно просматриваю список файлов с одной строкой и, в частности, не имеет другой строки? Кроме того, я хочу оценить текст файлов, а не имена файлов.


Вывод:

В соответствии с комментариями я закончил использование:

find . -name "*.html" -exec grep -lR 'base\-maps' {} \; | xargs grep -L 'base\-maps\-bot'

Это возвращенные файлы с "базовыми картами", а не "base-maps-bot". Спасибо!

4b9b3361

Ответ 1

Попробуйте следующее:

grep -rl <string-to-match> | xargs grep -L <string-not-to-match>

Объяснение: grep -lr делает grep рекурсивно (r) выводит список (l) всех файлов, содержащих <string-to-match>. xargs перебирает эти файлы, вызывая grep -L для каждого из них. grep -L будет выводить только имя файла, если файл не содержит <string-not-to-match>.

Ответ 2

Использование xargs в ответах выше не требуется; вы можете достичь такой же цели:

find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print

grep -q означает, что выполняется тихо, но возвращает код выхода, указывающий, было ли найдено совпадение; find может затем использовать этот код выхода, чтобы определить, продолжать ли выполнение остальных его опций. Если -exec grep -q <string-to-match> {} \; возвращает 0, то он будет продолжать выполнение -not -exec grep -q <string-not-to-match>{} \;. Если это также возвращает 0, оно будет продолжаться, чтобы выполнить -print, который печатает имя файла.

Как заметил еще один ответ, использование find таким образом имеет большие преимущества перед grep -Rl, когда вы хотите искать файлы определенного типа. Если, с другой стороны, вы действительно хотите искать все файлы, grep -Rl, вероятно, быстрее, так как он использует один grep процесс для первого фильтра для всех файлов вместо отдельного процесса grep для каждого файла.

Ответ 3

Эти ответы кажутся не такими, как строки BOTH. Следующая команда должна работать лучше:

grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'

Ответ 4

Вот более общая конструкция:

find . -name <nameFilter> -print0 | xargs -0 grep -Z -l <patternYes> | xargs -0 grep -L <patternNo>

Эта команда выводит файлы, имя которых соответствует <nameFilter> (скорректируйте предикаты find по мере необходимости), которые содержат <patternYes>, но не содержат <patternNo>.

Усовершенствования:

  • Он работает с именами файлов, содержащими пробелы.
  • Он позволяет фильтровать файлы по имени.

Если вам не нужно фильтровать по имени (часто нужно рассмотреть все файлы в текущем каталоге), вы можете удалить find и добавить -R к первому grep:

grep -R -Z -l <patternYes> | xargs -0 grep -L <patternNo>

Ответ 5

находить. -maxdepth 1 -name "*.py" -exec grep -L "строка, которая не соответствует" {} \;

Эта команда получит все ".py" файлы, которые не содержат "string-not-to-match" в одном каталоге.