To pytanie ma już tutaj odpowiedzi :
Komentarze
Odpowiedź
GNU grep
Powinno być trochę szybciej, ponieważ druga grep
może działać na liście plików.
grep -lZ "foo" * | xargs -0 grep -l "321"
POSIX grep with find
find
jest bardziej przydatne, jeśli chcesz przeszukiwać katalogi rekurencyjne (w takim przypadku zgub -mindepth
i -maxdepth
options.
find . -mindepth 1 -maxdepth 1 -type f -exec grep -q "foo" {} \; -exec grep -l "321" {} +
Komentarze
Answer
Możesz to zrobić za pomocą krótkiego skryptu:
for FILE in * do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE done
Możesz to również zrobić w jednej linii:
for FILE in *; do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE; done
grep
zwraca 0 (prawda), jeśli znalazł ciąg, a &&
rozdzielenie poleceń oznacza, że druga będzie działać tylko wtedy, gdy pierwsza będzie prawdziwa. Opcja -q
zapewnia, że grep
nic nie wyświetla.
Echo będzie działać tylko wtedy, gdy oba ciągi będą znalezione w tym samym pliku.
Pomyślałem o innym sposobie zrobienia tego. Ten sposób będzie prawdopodobnie bardziej wydajny, jeśli dane pliki są większe niż zainstalowana pamięć RAM, ponieważ wystarczy tylko grep
przejść przez każdy plik raz.
for FILE in * do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE done
i wersja jednowierszowa:
for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
Komentarze
Odpowiedź
Dziwne. U mnie działają oba warianty (grep (GNU grep) 2.13):
grep "foo\|321" grep -E "foo|321"
Edytuj 1 – pokaż pliki tylko z obydwoma dopasowaniami
Odpowiedź for file in *
działa, ale może stać się koszmarem wydajności (w przypadku dużych ilości plików ): co najmniej dwa procesy na plik. To jest szybsze (w świecie GNU):
find . -type f -print0 | xargs -0 -r grep --files-with-matches --null -- string1 | xargs -0 -r grep --files-with-matches -- string2
string1 powinien być tym, który daje mniej dopasowań.
Komentarze
Odpowiedź
Zasadniczo, aby znaleźć wszystkie pliki, w tym określony ciąg znaków w katalogu, możesz użyć:
grep -lir "pattern" /path/to/the/dir
-
-l
: aby wykonać to skanowanie zatrzyma się przy pierwszym dopasowaniu
-
-i
: zignoruje rozróżnienia wielkości liter zarówno we wzorcu, jak i plikach wejściowych
-
-r
: przeszukaj wszystkie pliki w katalogu, rekurencyjnie
Aby wyszukać dwa wzorce, spróbuj tego:
grep -lr "321" $(grep -lr "foo" /path/to/the/dir)
Komentarze
Odpowiedź
Powinno być
grep -e "foo" -e "321" *
Użyj -e dla wielu wzorców
EDYTUJ
Jeśli potrzebujesz dopasowania obu:
grep -e ".*foo.*321.*" *
Jeśli kolejność nie ma znaczenia:
grep -e ".*foo.*321.*" ".*321.*foo.*" *
Komentarze