Com GNU ou OpenBSD grep :
grep -L "string" ./* | grep -c /
Eu li a pergunta sobre como descobrir o número de arquivos que contêm uma determinada string. Isso é possível com grep -l "string" * | wc -l .
É possível inverter isso, encontrando o número de arquivos não contendo a string de destino? Eu tentei adicionar a opção -v , mas isso não parece produzir o resultado correto.
Outra maneira POSIX:
c=0
for f in *; do
[ -d "$f" ] && continue
{ grep -q string || c=$(($c + 1)); } < "$f"
done
echo "$c"
Ao redirecionar o grupo de comando em vez de grep sozinho, evitamos contar como 1 os arquivos que não podemos abrir (como arquivos para os quais não temos permissão de leitura, ou * se não houver arquivos não ocultos no diretório atual).
Com o GNU grep , o equivalente seria:
grep -d skip -L foo ./* | grep -c /
Note que você não pode usar wc -l , pois nomes de arquivos podem ser feitos de várias linhas. Ter ./ também evita problemas com nomes de arquivos que começam com - ou são - (que -- não funciona). Note que ele ignora arquivos de ponto.
Aqui está uma maneira compatível com POSIX, caso você não tenha grep -L :
for file in *; do
awk '/string/ { found=1; exit } END{ if(!found) { printf "x" } }' < "$file"
done | wc -c
Outra maneira POSIX usando apenas grep e 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\""
Dependendo da quantidade de arquivos que você deseja pesquisar, é aconselhável consultar ack-grep . O motivo, porque ack-grep é muito mais rápido que good'ol grep e o CLI é quase idêntico.
ack-grep -Lur "some string" * | wc -l
com zsh :
( arr=(./*(.N^e_'grep -q PATTERN $REPLY'_)); print ${#arr}; )
Isso salva os nomes dos arquivos que não contêm PATTERN em uma matriz e retorna o número de elementos na matriz. Ele usa qualificadores de glob : . seleciona somente arquivos regulares (adicione D a incluir arquivos ocultos), N ativa null glob e a negada ( ^ ) e string: ^e_'grep -q PATTERN $REPLY'_ desmarca mais os nomes de arquivo para os quais o código de shell entre as aspas retorna true .