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
.