2009-08-31 17 views
20

Io di solito utilizzare il seguente pipeline per grep per una particolare stringa di ricerca e tuttavia ignorare certi altri modelli:multipla ricerca grep/ignore modelli

grep -Ri 64 src/install/ | grep -v \.svn | grep -v "file"| grep -v "2\.5" | grep -v "2\.6" 

può questo essere realizzato in maniera succinta? Sto usando GNU grep 2.5.3.

+0

L'utilità della risposta dipende anche che le stringhe sono suscettibili di modificare. Se l'unica stringa che cambia è "64" perché non crei una funzione o uno script di shell per questo? – tripleee

risposta

25

Basta pipe l'output non filtrata in una singola istanza di grep e utilizzare un regexp estesa a dichiarare ciò che si vuole ignorare:

grep -Ri 64 src/install/ | grep -v -E '(\.svn|file|2\.5|2\.6)' 

Edit: Per cercare più file magari provare

find ./src/install -type f -print |\ 
    grep -v -E '(\.svn|file|2\.5|2\.6)' | xargs grep -i 64 

Modifica: Ooh. Ho dimenticato di aggiungere il semplice trucco per fermare un uso cringeable di più istanze grep, vale a dire

ps -ef | grep something | grep -v grep 

sostituzione che, con

ps -ef | grep "[s]omething" 

elimina la necessità del secondo grep.

+2

Le parentesi devono essere quotate .. altrimenti si lamenta bash: errore di sintassi vicino a token imprevisto '(' –

+0

Aggiornato! Grazie. –

+0

C'è un bug nella soluzione e l'esempio nella mia domanda: il secondo grep corrisponderà alla linea attuale * e * il nome del file che appare nell'output del primo grep.Questo è un bene per ignorare '.svn' .. ma non altri pattern. –

1

Probabilmente si desidera utilizzare ack-grep che consente di escludere anche con regexp perl e di evitare tutte le directory VC, ideali per il grepping del codice sorgente.

+0

Grazie per il puntatore; per l'albero dei sorgenti puramente Python, attualmente utilizzo 'py.lookup' da http://pylib.org/ –

2

è possibile utilizzare awk al posto di grep

awk '/64/&&!/(\.svn|file|2\.[56])/' file 
+0

Questo sintonizza succintamente le righe da un singolo file, ma non riesce a fare la ricorsione dal primo grep. Ma può essere utilizzato fruttuosamente in combinazione con il suggerimento 'find | soluzione xargs'. Dovrebbe anche aggiungere la stampa del nome del file prima della partita per poter emulare completamente il comportamento di grep, comunque. – tripleee

7

Utilizzare l'opzione -e per specificare più modelli:

grep -Ri 64 src/install/ | grep -v -e '\.svn' -e file -e '2\.5' -e '2\.6' 

Potreste anche essere interessati a bandiera -F, il che indica che i modelli sono fissi stringhe invece di espressioni regolari. Ora non devi sfuggire al punto:

grep -Ri 64 src/install/ | grep -vF -e .svn -e file -e 2.5 -e 2.6 

Ho notato che eri fuori ".svn". Probabilmente vorrai saltare qualsiasi directory chiamata ".svn" nel tuo grep ricorsivo iniziale. Se fossi in te, farei questo, invece:

grep -Ri 64 src/install/ --exclude-dir .svn | grep -vF -e file -e 2.5 -e 2.6 
0

Il seguente script rimuovere tutti i file ad eccezione di un elenco di file:

echo cleanup_all [email protected] 


if [[ $# -eq 0 ]]; then 
FILES=`find . -type f` 
else 
EXCLUDE_FILES_EXP="(" 
for EXCLUDED_FILE in [email protected] 
do 
    EXCLUDE_FILES_EXP="$EXCLUDE_FILES_EXP./$EXCLUDED_FILE|" 
done 
# strip last char 
EXCLUDE_FILES_EXP="${EXCLUDE_FILES_EXP%?}" 
EXCLUDE_FILES_EXP="$EXCLUDE_FILES_EXP)" 
echo exluded files expression : $EXCLUDE_FILES_EXP 

    FILES=`find . -type f | egrep -v $EXCLUDE_FILES_EXP` 
fi 

echo removing $FILES 

for FILE in $FILES 
do 
    echo "cleanup: removing file $FILE" 
    rm $FILE 
done 
Problemi correlati