Количество файлов, не содержащих заданную строку

Я прочитал вопрос о том, как узнать количество файлов, содержащих определенную строку. Это возможно с помощью grep -l "string" * | wc -l grep -l "string" * | wc -l .

Можно ли инвертировать это, найдя количество файлов, не содержащих целевую строку? Я попробовал добавить параметр -v , но это, похоже, не приводит к правильному результату.

  • Использовать awk, чтобы найти первое вхождение
  • Как правильно использовать / usr / xpg4 / bin / grep -F
  • Как искать слово после определенной строки в файле в Linux?
  • Проблема с журналом реального времени, проверяющим хвост трубопровода, grep и разрез
  • Oneliner для определения переменных верблюда
  • Копирование файлов, содержащих определенную структуру сохранения текста
  • grep, чтобы найти экземпляры «Foo», где «Bar» не отображается в пределах 10 строк
  • Сценарий Bash с несколькими строками и Grep
  • 6 Solutions collect form web for “Количество файлов, не содержащих заданную строку”

    С GNU или OpenBSD grep :

     grep -L "string" ./* | grep -c / 

    Другой способ POSIX:

     c=0 for f in *; do [ -d "$f" ] && continue { grep -q string || c=$(($c + 1)); } < "$f" done echo "$c" 

    Перенаправляя группу команд вместо grep одиночку, мы не учитываем как 1 файлы, которые мы не можем открыть (например, файлы, для которых у нас нет разрешения на чтение, или * если в текущем каталоге нет скрытого файла).

    С GNU grep эквивалент будет:

     grep -d skip -L foo ./* | grep -c / 

    Обратите внимание: вы не можете использовать wc -l поскольку имена файлов могут быть сделаны из нескольких строк. Наличие ./ также позволяет избежать проблем с именами файлов, которые начинаются с - или есть - (которые -- не работают). Обратите внимание, что он игнорирует файлы точек.

    Вот как POSIX-совместимый способ, если у вас нет grep -L :

     for file in *; do awk '/string/ { found=1; exit } END{ if(!found) { printf "x" } }' < "$file" done | wc -c 

    Другой способ POSIX, использующий только grep и wc :

     COUNT_FILES=0 for i in *;do COUNT_FILES=$((COUNT_FILES+1));done MATCHES=$(grep -l "string" * | wc -l) NON_MATCHES=$((COUNT_FILES - MATCHES)) echo "There are $NON_MATCHES files not matching \"string\"" 

    В зависимости от того, сколько файлов вы хотите найти, это хороший совет, чтобы взглянуть на ack-grep . Причина, потому что ack-grep намного быстрее, чем good'ol grep и CLI почти идентичен.

    ack-grep -Lur "some string" * | wc -l

    С zsh :

     ( arr=(./*(.N^e_'grep -q PATTERN $REPLY'_)); print ${#arr}; ) 

    Это сохраняет имена файлов, которые не содержат PATTERN в массив и возвращает количество элементов в массиве. Он использует квалификаторы glob :. выбирает только обычные файлы (добавляет D для включения скрытых файлов), N включает null glob и строку с отрицанием ( ^ ) e : ^e_'grep -q PATTERN $REPLY'_ далее ^e_'grep -q PATTERN $REPLY'_ имена файлов, для которых код оболочки между кавычки true .

    Interesting Posts
    Linux и Unix - лучшая ОС в мире.