2009-08-31 5 views
20

Normalerweise verwende ich die folgende Pipeline für einen bestimmten Suchbegriff grep und noch einige andere Muster ignorieren:Multiple grep Suche/Ignoriermuster

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

kann dies in einer prägnanten Art und Weise erreicht werden? Ich benutze GNU Grep 2.5.3.

+0

Die Nützlichkeit der Antwort hängt auch von dem Zeichenketten sind wahrscheinlich Veränderung. Wenn die einzige sich ändernde Zeichenfolge "64" ist, warum erstellen Sie dafür kein Funktions- oder Shell-Skript? – tripleee

Antwort

25

Gerade Rohr Ihre ungefilterte Ausgabe in einer einzigen Instanz von grep und verwenden einen erweiterten regulären Ausdruck zu erklären, was Sie ignorieren wollen:

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

Edit: mehrere Dateien vielleicht suchen versuchen

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

Bearbeiten: Ooh. Ich habe vergessen, den einfachen Trick hinzufügen, um eine cringeable Verwendung mehrerer grep Instanzen zu stoppen, und zwar

ps -ef | grep something | grep -v grep 

Ersetzen dass mit

ps -ef | grep "[s]omething" 

die Notwendigkeit des zweiten grep entfernt.

+2

Die Klammern müssen zitiert werden. Ansonsten beschwert sich bash: Syntaxfehler in der Nähe des unerwarteten Tokens '(' –

+0

Aktualisiert! Danke. –

+0

Es gibt einen Fehler in Ihrer Lösung und das Beispiel in meiner Frage: der zweite grep wird der tatsächlichen Zeile * und entsprechen * Der Dateiname, der in der Ausgabe des ersten Grep erscheint. Das ist gut für das Ignorieren '.svn' .. aber nicht andere Muster. –

1

Sie möchten vielleicht ack-grep verwenden, die mit Perl Regexp auch ausschließen können und alle VC-Verzeichnisse zu vermeiden, ideal für den Quellcode Quellcode.

+0

Danke für den Zeiger; Für den reinen Python-Source-Tree verwende ich zur Zeit 'py.lookup' von http://pylib.org/ –

2

Sie awk statt grep

mehrere Muster verwenden können
awk '/64/&&!/(\.svn|file|2\.[56])/' file 
+0

. Dies druckt Linien aus einer einzigen Datei, aber nicht die Rekursion von der ersten grep. Aber es kann fruchtbar in Kombination mit dem vorgeschlagenen 'finden | verwendet werden Xargs' Lösung. Es sollte jedoch auch vor dem Match das Drucken des Dateinamens hinzugefügt werden, um das Grep-Verhalten vollständig zu emulieren. – tripleee

7

Verwenden Sie die -e Option angeben:

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

Sie könnten auch in der -F Flagge interessiert sein, was darauf hindeutet, dass die Muster festgelegt sind Zeichenfolgen anstelle von regulären Ausdrücken. Jetzt müssen Sie nicht den Punkt entkommen müssen:

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

ich bemerkt, dass Sie wurden greppen out „.svn“. Wahrscheinlich möchten Sie alle Verzeichnisse namens ".svn" in Ihrem ersten rekursiven Grep überspringen. Wenn ich Sie wäre, würde ich diese stattdessen tun:

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

Das folgende Skript alle Dateien außer einer Liste von Dateien entfernen wird:

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