Jak radzić sobie ze spacjami w nazwach plików podczas korzystania z xargs podczas wyszukiwania wyników?

28

Jedną z moich powszechnych praktyk jest wykonywanie greps na wszystkich plikach określonego typu, np. Znajdowanie wszystkich plików HTML zawierających słowo „rumpus”. Aby to zrobić, używam

find /path/to -name "*.html" | xargs grep -l "rumpus"

Czasami findzwraca plik ze spacją w nazwie, np my new file.html. Po xargsprzekazaniu tego grepotrzymuję jednak następujące błędy:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory

Widzę, co się tutaj dzieje: albo potok albo xargstraktuje spacje jako separatory między plikami. Jednak przez całe życie nie mogę wymyślić, jak temu zapobiec. Czy można to zrobić za pomocą find+ xargs? Czy też muszę użyć zupełnie innego polecenia?

abeger
źródło

Odpowiedzi:

29

Posługiwać się

find ... -print0 | xargs -0 ...

na przykład

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

ze strony podręcznika wyszukiwania

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
user9517 obsługuje GoFundMonica
źródło
15

Nie musisz używać xargs , ponieważ find może wykonywać same polecenia. Robiąc to, nie musisz się martwić, że powłoka interpretuje znaki w nazwie.

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

ze strony podręcznika wyszukiwania

-exec polecenie {} +
Ten wariant akcji -exec uruchamia określone polecenie na wybranych plikach, ale linia poleceń jest budowana przez dołączenie każdej wybranej nazwy pliku na końcu; całkowita liczba wywołań polecenia będzie znacznie mniejsza niż liczba dopasowanych plików. Wiersz poleceń jest zbudowany w taki sam sposób, jak xargs buduje wiersze poleceń. W poleceniu dozwolona jest tylko jedna instancja „{}”. Polecenie jest wykonywane w katalogu startowym.

Sciurus
źródło
Głosowałbym za tym, ale nie wyszedłem na dziś - zrobię to jutro.
user9517 obsługuje GoFundMonica
1
@Iain - proszę bardzo (zgadzam się przy okazji).
Eduardo Ivanec
Używając funkcji find, nadal brakuje Ci funkcji xargs, a ponadto musisz poradzić sobie z głupimi regułami cytowania. Zobacz argument -P dla xargs, jeśli masz więcej niż jeden rdzeń / procesor.
Slartibartfast
8

Jeśli find a xarg wersje na komputerze nie obsługuje -print0i -0przełączniki (na przykład AIX znaleźć i xargs) można użyć to:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

Tutaj sed zajmie się ucieczką z przestrzeni dla xargów.

Jan Ptáčník
źródło
Pomogło mi to, ponieważ miałem długą listę nazw plików, które były trudne do wytworzenia, z których korzystałem kilka razy. Nie mogę po prostu findznowu ich wszystkich.
Scott M.