2009-08-31 13 views
20

Zwykle używam następujące rurociąg do grep do wyszukiwania określonego ciągu znaków i jeszcze ignorować niektórych innych wzorców:Multiple wyszukiwania grep/ignore wzory

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

Można to osiągnąć w zwięzły sposób? Używam GNU grep 2.5.3.

+0

Przydatność odpowiedź zależy również od których łańcuchy są prawdopodobne zmiana. Jeśli jedynym zmiennym łańcuchem jest "64", dlaczego nie stworzysz dla niego funkcji lub skryptu powłoki? – tripleee

Odpowiedz

25

Wystarczy rura Twój niefiltrowane wyjścia do jednej instancji grep i używać rozszerzonego regexp oświadczyć co chcesz ignorować:

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

Edit: Aby wyszukać wiele plików może spróbować

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

Edytuj: Ooo. Zapomniałam dodać prosty trik, aby zatrzymać cringeable użycie wielu przypadkach grep, mianowicie

ps -ef | grep something | grep -v grep 

Wymiana że z

ps -ef | grep "[s]omething" 

eliminuje potrzebę drugiego grep.

+2

Nawiasy muszą być cytowane .. w przeciwnym razie bash narzeka: błąd składniowy w pobliżu nieoczekiwanego tokena '(' –

+0

Zaktualizowany! Dzięki. –

+0

Jest jeden błąd w twoim rozwiązaniu i przykład w moim pytaniu: drugi grep będzie pasował do rzeczywistej linii * i * nazwa pliku, który pojawia się na wyjściu pierwszego pliku grep. Jest to dobre dla zignorowania '.svn' .. ale nie dla innych wzorów –

1

Być może zechcesz użyć ack-grep, które pozwalają na wykluczenie również z perge regexp i omijaj wszystkie katalogi VC, idealne do grepowania kodu źródłowego.

+0

Dzięki za wskaźnik; dla czystego drzewa źródłowego Pythona używam 'py.lookup' z http://pylib.org/ –

2

można użyć awk zamiast grep

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

To zwięźle drukuje linie z pojedynczego pliku, ale nie wykonuje rekursji od pierwszego grepa. Ale można go owocnie wykorzystać w połączeniu z sugerowanym 'find | Rozwiązanie xargs'. Powinieneś także dodać drukowanie nazwy pliku przed meczem, aby w pełni emulować zachowanie grep. – tripleee

7

Użyj opcji -e podać wiele wzorów:

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

Możesz być także zainteresowany flaga -F, co wskazuje, że wzorce są stałe ciągi zamiast wyrażeń regularnych. Teraz nie musisz uciekać z kropki:

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

Zauważyłem, że pozbyłeś się ".svn". Prawdopodobnie chcesz pominąć wszystkie katalogi o nazwie ".svn" w początkowym rekursywnym grep. Gdybym był tobą, chciałbym to zrobić w zamian:

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

Poniższy skrypt usunie wszystkie pliki z wyjątkiem listy plików:

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