Come posso ricorsivamente grep
tutte le directory e le sottodirectory?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
non funziona per me su Redhat Linux. Viene visualizzato l'errore "Nessuna corrispondenza".
Come posso ricorsivamente grep
tutte le directory e le sottodirectory?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
non funziona per me su Redhat Linux. Viene visualizzato l'errore "Nessuna corrispondenza".
Risposte:
grep -r "texthere" .
Il primo parametro rappresenta l'espressione regolare da cercare, mentre il secondo rappresenta la directory da cercare. In questo caso, .
indica la directory corrente.
Nota: questo funziona con GNU grep e su alcune piattaforme come Solaris è necessario utilizzare GNU grep invece dell'implementazione legacy. Per Solaris questo è il ggrep
comando.
AIX 5.3
ad esempio.
Se conosci l'estensione o il modello del file che desideri, un altro metodo è utilizzare l' --include
opzione:
grep -r --include "*.txt" texthere .
Puoi anche menzionare i file da escludere --exclude
.
Se cerchi frequentemente il codice, Ag (The Silver Searcher) è un'alternativa molto più veloce a grep, che è personalizzata per la ricerca del codice. Ad esempio, è ricorsivo per impostazione predefinita e ignora automaticamente i file e le directory elencati .gitignore
, quindi non è necessario continuare a passare le stesse ingombranti opzioni di esclusione per grep o find.
=
funzionare perfettamente su Ubuntu. PS: dovrebbe essere uno spazio con backtick, ma il parser SO markdown non è riuscito.
grep
, non per l'Ag, solo per quello che sai :)
--include "*.txt" --include "*.TXT"
Anche:
find ./ -type f -print0 | xargs -0 grep "foo"
ma grep -r
è una risposta migliore.
find . -type f -exec grep "foo" '{}' \;
funziona bene dove supportato.
find ./ -type f -print0 | xargs -0 grep "foo"
Ora uso sempre (anche su Windows con GoW - Gnu su Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Ciò include le seguenti opzioni:
--include=PATTERN
Recurse nelle directory cercando solo la corrispondenza dei file
PATTERN
.
-n, --line-number
Prefisso ogni riga di output con il numero di riga all'interno del suo file di input.
(Nota: phuclv aggiunge nei commenti che -n
diminuiscono molto le prestazioni , quindi potresti voler saltare quell'opzione )
-R, -r, --recursive
Leggi tutti i file in ciascuna directory, in modo ricorsivo; questo equivale
-d recurse
all'opzione.
-H, --with-filename
Stampa il nome file per ogni corrispondenza.
-I
Elabora un file binario come se non contenesse dati corrispondenti;
questo equivale--binary-files=without-match
all'opzione.
E posso aggiungere ' i
' ( -nRHIi
), se voglio risultati senza distinzione tra maiuscole e minuscole.
Posso ottenere:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
dell'opzione) alle cartelle.
*
o .
è un modello glob (interpretato dalla shell): unix.stackexchange.com/a/64695/7490 . ' .
' selezionerà anche dotfile o dot folder (come .git/
)
grep -rnI
ma poi ho imparato che -n
diminuisce molto le prestazioni, quindi lo uso solo quando è veramente necessario e normalmente lo userò-rI
Nei sistemi POSIX, non trovi i -r
parametri per grep
e grep -rn "stuff" .
non funzionerai, ma se usi il find
comando:
find . -type f -exec grep -n "stuff" {} \; -print
Concordato da Solaris
e HP-UX
.
-exec
opzione - simbolo {}
è un riferimento al nome del file che attualmente trovata da find
strumento (che è quello di fare qualcosa con il nome del file che abbiamo trovato), anche -exec
l'opzione deve essere chiuso con ;
il simbolo (a marchio porre fine dei comandi exec), ma perché questo è tutto in esecuzione in una shell quel simbolo dovrebbe essere sfuggito .. e infine l' -print
opzione consente find
allo strumento di stampare i nomi dei file trovati sullo schermo.
**
L'uso grep -r
funziona, ma può essere eccessivo, specialmente nelle cartelle di grandi dimensioni.
Per un utilizzo più pratico, ecco la sintassi che utilizza la sintassi globbing ( **
):
grep "texthere" **/*.txt
che greps solo file specifici con pattern selezionato pattern. Funziona con shell supportate come Bash +4 o zsh .
Per attivare questa funzione, eseguire: shopt -s globstar
.
Vedi anche: Come posso trovare tutti i file contenenti testo specifico su Linux?
git grep
Per i progetti sotto il controllo della versione di Git, utilizzare:
git grep "pattern"
che è molto più veloce.
ripgrep
Per progetti più grandi, lo strumento di grepping più veloce è quello ripgrep
che greps i file in modo ricorsivo per impostazione predefinita:
rg "pattern" .
È costruito sulla base del motore regex di Rust che utilizza automi finiti, SIMD e ottimizzazioni letterali aggressive per rendere la ricerca molto veloce. Controlla qui l'analisi dettagliata .
Per trovare il nome di files
con path
ricorsivamente contenente il particolare string
uso di sotto di comando per UNIX
:
find . | xargs grep "searched-string"
per Linux
:
grep -r "searched-string" .
trova un file sul UNIX
server
find . -type f -name file_name
trova un file sul server LINUX
find . -name file_name
Se desideri seguire solo le directory effettive e non i collegamenti simbolici,
grep -r "thingToBeFound" directory
Se vuoi seguire i collegamenti simbolici e le directory effettive (fai attenzione all'infinita ricorsione),
grep -R "thing to be found" directory
Dal momento che stai provando a ricorrere in greece in modo ricorsivo, potrebbero essere utili anche le seguenti opzioni:
-H: outputs the filename with the line
-n: outputs the line number in the file
Quindi, se si desidera trovare tutti i file contenenti Darth Vader nella directory corrente o in qualsiasi sottodirectory e acquisire il nome file e il numero di riga, ma non si desidera che la ricorsione segua i collegamenti simbolici, il comando sarebbe
grep -rnH "Darth Vader" .
Se vuoi trovare tutte le menzioni della parola cat nella directory
/home/adam/Desktop/TomAndJerry
e sei attualmente nella directory
/home/adam/Desktop/WorldDominationPlot
e vuoi catturare il nome del file ma non il numero di riga di qualsiasi istanza della stringa "cats" e vuoi che la ricorsione segua i collegamenti simbolici se li trova, puoi eseguire uno dei seguenti
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Fonte:
con "grep --help" in esecuzione
Una breve introduzione ai collegamenti simbolici, per chiunque legga questa risposta e confuso dal mio riferimento a loro: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag è il mio modo preferito per farlo ora github.com/ggreer/the_silver_searcher . È praticamente la stessa cosa di Ack ma con qualche ottimizzazione in più.
Ecco un breve benchmark. Svuoto la cache prima di ogni test (vedi /ubuntu/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Questo dovrebbe funzionare:
grep -R "texthere" *
Se stai cercando un contenuto specifico in tutti i file da una struttura di directory, puoi usarlo find
poiché è più chiaro cosa stai facendo:
find -type f -exec grep -l "texthere" {} +
Si noti che -l
(downcase di L) mostra il nome del file che contiene il testo. Rimuovilo se invece desideri stampare la corrispondenza stessa. Oppure usa -H
per ottenere il file insieme alla corrispondenza. Tutti insieme, altre alternative sono:
find -type f -exec grep -Hn "texthere" {} +
Dove -n
stampa il numero di riga.
find
soluzione sia per evitare l'uso xargs
e l'uso non necessari +
anziché \;
con -exec
, evitando così tonnellate di lanci di processi non necessari. :-)
Questo è quello che ha funzionato per il mio caso sulla mia macchina attuale (git bash su Windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Dimentico sempre -print0 e -0 per i percorsi con spazi.
EDIT: il mio strumento preferito ora è invece ripgrep: https://github.com/BurntSushi/ripgrep/releases . È davvero veloce e ha impostazioni predefinite migliori (come ricorsivo per impostazione predefinita). Stesso esempio della mia risposta originale ma usando ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(periodo di preavviso alla fine)
(^ credito: https://stackoverflow.com/a/1987928/1438029 )
Una precisazione:
grep -r "texthere" /
(grep ricorsivamente tutte le directory e le sottodirectory)
grep -r "texthere" .
(grep ricorsivamente queste directory e sottodirectory)
grep [options] PATTERN [FILE...]
[opzioni]
-R, -r, --recursive
Leggi tutti i file in ciascuna directory, in modo ricorsivo.
Ciò equivale all'opzione
-d recurse
o--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
Nel 2018, vuoi usare ripgrep
o the-silver-searcher
perché sono molto più veloci delle alternative.
Ecco una directory con 336 sottodirectory di primo livello:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
Su OSX, questo viene installato ripgrep
: brew install ripgrep
. Questo consente di installare silver-searcher
: brew install the_silver_searcher
.
rg
ha un vantaggio considerevole rispetto al mettere insieme un comando ricorsivo grep da zero. Usando rg
: rg foo
. L'utilizzo di strumenti unix: find . | xargs grep foo
. E se uno qualsiasi dei tuoi file contiene un preventivo, devi usarlo find . -print0 | xargs -0 grep foo
. Ricorderai che se lo usi qualche volta all'anno?
find . -type f -exec grep 'regex' {} +
che è davvero facile ricordare se usi questi strumenti con regolarità. Ma probabilmente dovresti comunque eseguire ctags
o etags
sul tuo albero dei sorgenti se devi trovare roba frequentemente.
Nel mio server IBM AIX (versione del sistema operativo: AIX 5.2), utilizzare:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
questo stamperà il percorso / nome del file e il relativo numero di riga nel file come:
./inc/xxxx_x.h
2865: / ** Descrizione: stringYouWannaFind * /
comunque, funziona per me:)
Di seguito sono riportati i comandi per la ricerca String
ricorsiva su Unix
e Linux
ambiente.
per UNIX
comando è:
find . -name "string to be searched" -exec grep "text" "{}" \;
per Linux
comando è:
grep -r "string to be searched" .
Per un elenco di flag disponibili:
grep --help
Restituisce tutte le corrispondenze per il regexp texthere nella directory corrente, con il numero di riga corrispondente:
grep -rn "texthere" .
Restituisce tutte le corrispondenze per texthere , a partire dalla directory principale, con il numero di riga corrispondente e ignorando il caso:
grep -rni "texthere" /
bandiere utilizzate qui:
-r
ricorsivo -n
stampare il numero di riga con l'output -i
ignora il casoImmagino sia questo ciò che stai cercando di scrivere
grep myText $(find .)
e questo potrebbe essere qualcos'altro utile se vuoi trovare i file grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Si noti che una serie find . -type f | xargs grep whatever
di soluzioni verrà eseguita in errori "Elenco argomenti troppo lungo" quando sono presenti troppi file corrispondenti a find.
La scommessa migliore è grep -r
ma se non è disponibile, utilizzare find . -type f -exec grep -H whatever {} \;
invece.
xargs
è in particolare una soluzione alternativa al problema "Elenco argomenti troppo lungo".
find . -type f | xargs -L 100 grep whatever
xargs
è standardizzato per avere questo comportamento pronto all'uso. "L' xargs
utilità deve limitare la lunghezza della riga di comando in modo tale che quando viene invocata la riga di comando, l'argomento combinato e gli elenchi di ambienti ... non devono superare {ARG_MAX} -2048 byte."
Ecco una funzione ricorsiva (testata leggermente con bash e sh) che attraversa tutte le sottocartelle di una determinata cartella ($ 1) e utilizza le grep
ricerche per una determinata stringa ($ 3) in determinati file ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Eseguendolo e un esempio di output:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename