Como você contaria cada ocorrência de um termo em todos os arquivos no diretório atual? - e subdiretórios (?)
Eu li que para fazer isso você usaria grep
; qual é o comando exato?
Além disso, é possível o acima com algum outro comando?
Como você contaria cada ocorrência de um termo em todos os arquivos no diretório atual? - e subdiretórios (?)
Eu li que para fazer isso você usaria grep
; qual é o comando exato?
Além disso, é possível o acima com algum outro comando?
Respostas:
Usando grep
+ wc
(isso atende a várias ocorrências do termo na mesma linha):
grep -rFo foo | wc -l
-r
in grep
: pesquisa recursivamente na hierarquia de diretórios atual;-F
in grep
: corresponde a uma sequência fixa em vez de a um padrão;-o
in grep
: imprime apenas correspondências;-l
in wc
: imprime a contagem das linhas;% tree
.
├── dir
│ └── file2
└── file1
1 directory, 2 files
% cat file1
line1 foo foo
line2 foo
line3 foo
% cat dir/file2
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8
PCREs
não deve ser utilizado, uma vez que são experimentais
-F
provavelmente seria mais rápido.
-F
vez de -P
. Obrigado pela ótima sugestão, atualizando usando -F
, que realmente se encaixa melhor aqui.
grep -Rc [term] *
vai fazer isso. O -R
sinalizador significa que você deseja pesquisar recursivamente o diretório atual e todos os seus subdiretórios. O *
é um seletor de arquivos que significa: todos os arquivos. O -c
sinalizador produz grep
apenas o número de ocorrências. No entanto, se a palavra ocorrer várias vezes em uma única linha, ela será contada apenas uma vez.
De man grep
:
-r, --recursive
Read all files under each directory, recursively, following symbolic links only if they are on the command line.
This is equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
Se você não possui links simbólicos no seu diretório, não há diferença.
-c
bandeira a grep
. Então o grep conta-se e você não precisa dowc
--
antes*
*
arquivo será expandido apenas para arquivos que não sejam dot-dot; portanto, você perderá todos eles. Faz mais sentido usar apenas "." já que você vai processar argumentos recursivamente de qualquer maneira - e isso obterá arquivos de ponto. O maior problema aqui é que isso pode ser o número de linhas, não o número de ocorrências de uma palavra. Se o termo aparecer várias vezes em uma linha, ele será contado apenas uma vez por "grep -c"
Em um pequeno script python:
#!/usr/bin/env python3
import os
import sys
s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
for f in files:
f = root+"/"+f
try:
n = n + open(f).read().count(s)
except:
pass
print(n)
count_string.py
.Execute- o no diretório com o comando:
python3 /path/to/count_string.py <term>
# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
for f in files:
# join the path(s) above the file and the file itself
f = root+"/"+f
# try to read the file (will fail if the file is unreadable for some reason)
try:
# add the number of found occurrences of <term> in the file
n = n + open(f).read().count(s)
except:
pass
print(n)
root
e f
para?
root
é o caminho para o arquivo, incluindo "acima" o diretório atual, f
é o arquivo Como alternativa, os.path.join()
poderia ser usado, mas é mais detalhado.
n = n + open(f).read().count(s)
?