Lepiej wyjaśnić na przykładach.

Mogę:

find . -name "*.py" -type f > output.txt 

Ale jak mogę zapisać wynik w tym samym pliku dla:

find . -name "*.py" -type f -exec grep "something" {} \ 

Nie mogę po prostu zrobić

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt 

Odpowiedź

Jeśli dobrze Cię rozumiem, oto co chcesz zrobić:

find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt 

Znajdź wszystkie pliki z rozszerzeniem .py, grep tylko wiersze zawierające something i zapisz wiersze w output.txt. Jeśli plik output.txt istnieje, zostanie obcięty, w przeciwnym razie zostanie utworzony.

Używając -exec:

find . -name "*.py" -exec grep "something" {} \; > output.txt 

Łączę Chrisa Downsa komentarz tutaj: Powyższe polecenie spowoduje wykonanie grep tyle razy, ile find znajdzie ścieżki, które przejdą dane testy (tylko jeden powyżej). Jeśli jednak zmienisz \; na +, grep zostanie wywołany z wieloma nazwami ścieżek from find (do pewnego limitu).

Zobacz pytanie Używając średnika (;) kontra plus ( +) z exec w find , aby uzyskać więcej informacji na ten temat.

Komentarze

  • Użyj + zamiast \;, znacznie skróci czas wykonywania (ponieważ będzie zawierał argumenty przed wykonaniem do ARG_MAX).
  • Teraz rozumiem moc xargs! Dzięki!
  • Użyj grep -H, jeśli chcesz dołączyć nazwę pliku do wyniku.
  • Użyj opcji 1. I dodaj LC_ALL=C tuż przed xargs, aby uzyskać dużo dodatkowej prędkości. Możesz też użyć flagi -P6 na xargs, aby działać równolegle z (w tym przypadku) 6 procesami (możesz zmienić liczbę od 6 do wyższego lub niższego, aby zobaczyć, co ' działa szybciej na twoim komputerze i podczas wyszukiwania). Źródła: unix.stackexchange.com/questions/131535/…
  • Korzystanie z + zamiast \; przekaże wiele plików do programu grep, a jeśli którykolwiek plik w tym zestawie zawiera tekst ' coś ', wszystkie te pliki przejdą test. Więc nie ' nie zrobisz tego, co chcesz.

Odpowiedź

Jeśli chcesz zapisać wszystkie pasujące wiersze we wszystkich plikach w output.txt, ostatnie polecenie działa, z wyjątkiem tego, że brakuje wymaganego ; na końcu polecenia.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt 

Jeśli chcesz, aby każde uruchomienie grep generowało wyjście do innego pliku, uruchom powłokę, aby obliczyć nazwę pliku wyjściowego i wykonać przekierowanie.

find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \; 

Komentarze

  • ostatni naprawdę fajny: D
  • Aby rozwinąć @gilles, odpowiedz, aby była trochę bardziej pouczająca, zwłaszcza jeśli lista plików, które ' jest duży, możesz zgłosić nazwę pliku (ścieżkę względną) każdego pliku wraz z wynikami grep ' ed, używając tego: find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt A jeśli ' chciałbyś zobaczyć e numery wierszy grep ' ed, możesz oczywiście użyć grep -n "something"

Odpowiedź

Dla przypomnienia, grep ma --include oraz --exclude argumenty, których można użyć do filtrowania przeszukiwanych plików:

grep -r --include="*.py" "something" > output.txt 

Komentarze

  • Co najmniej GNU grep tak.

Odpowiedź

Użyj tee:

find . -name "*.py" | tee output.txt | xargs grep "something" 

Zastrzeżenie: jeśli masz jakieś pliki ze znakami specjalnymi (w tym spacjami), które xargs i grep nie działają dobrze z (a file.txt zostanie zinterpretowany jako dwa pliki, a i file.txt). Alternatywą jest użycie -x lub -print0, ale którekolwiek z nich spowoduje zanieczyszczenie output.txt. -x użyje \ do zmiany znaczenia niektórych znaków specjalnych i będzie to output.txt.-print0 użyje bajtu zerowego jako separatora pól (co również wymaga xargs -0) i output.txt będzie wyglądać jak jedna długa, ciągła linia tekstu.

To, jak sobie z tym poradzisz, zależy od Ciebie.

Odpowiedź

grep -n CThread "`find . -name "*.cpp"`" 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *