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

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

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

  • REGEX и GREP - строка поиска, включая необязательные и статические слова
  • awk, sed, grep, perl ... которые распечатываются в этом случае?
  • Включение или в шаблон grep
  • sed, grep или tr, которая возвращает только латинские символы из файла UTF-8
  • вывод grep в rm
  • Как похоронить невидимую метку в строках текста?
  • Распечатайте до (и включив) n-е появление шаблона в строке
  • Идеи для анализа результатов netstat для активных подключений
  • 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 .

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