Come valuteresti ogni ricorrenza di un termine in tutti i file nella directory corrente? - e sottodirectory (?)
Ho letto che per fare questo useresti grep
; qual è il comando esatto?
Inoltre, è possibile quanto sopra con qualche altro comando?
Come valuteresti ogni ricorrenza di un termine in tutti i file nella directory corrente? - e sottodirectory (?)
Ho letto che per fare questo useresti grep
; qual è il comando esatto?
Inoltre, è possibile quanto sopra con qualche altro comando?
Risposte:
Usando grep
+ wc
(questo soddisferà più occorrenze del termine sulla stessa riga):
grep -rFo foo | wc -l
-r
in grep
: cerca ricorsivamente nella gerarchia di directory corrente;-F
in grep
: corrisponde a una stringa fissa anziché a una sequenza;-o
in grep
: stampa solo le corrispondenze;-l
in wc
: stampa il conteggio delle linee;% 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
non dovrebbero essere usati poiché sono sperimentali
-F
probabilmente sarebbe più veloce.
-F
invece di -P
. Grazie per il grande suggerimento, l'aggiornamento usando -F
, che in effetti si adatta meglio qui.
grep -Rc [term] *
lo farà. Il -R
flag indica che si desidera cercare ricorsivamente la directory corrente e tutte le sue sottodirectory. Il *
è un significato selettore di file: tutti i file. Il -c
flag rende in grep
output solo il numero di occorrenze. Tuttavia, se la parola appare più volte su una sola riga, viene contata una sola volta.
Da 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 non hai collegamenti simbolici nella tua directory, non c'è differenza.
-c
bandiera a grep
. Quindi grep conta se stesso e non è necessario ilwc
--
prima*
*
espanderà solo a file non dotfile, quindi ti perderai tutti quelli. Ha più senso usare solo "." dal momento che elaborerai gli argomenti in modo ricorsivo comunque - e questo otterrà file dot. Il problema più grande qui è che questa volontà potrebbe il numero di righe, non il numero di occorrenze di una parola. Se il termine appare più volte su una riga, verrà conteggiato una sola volta da "grep -c"
In un piccolo 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
.Eseguilo dalla directory con il 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 e f
per?
root
è il percorso del file incluso "sopra" la directory corrente, f
è il file. In alternativa, os.path.join()
potrebbe essere usato, ma è più dettagliato.
n = n + open(f).read().count(s)
?