Come posso gestire gli spazi nei nomi dei file quando uso xargs per trovare risultati?


28

Una delle mie pratiche comuni è eseguire greps su tutti i file di un certo tipo, ad esempio, trovare tutti i file HTML che contengono la parola "rumpus". Per farlo, io uso

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

Occasionalmente, findrestituirà un file con uno spazio nel suo nome come my new file.html. Quando viene xargspassato a grep, tuttavia, ottengo questi errori:

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

Vedo cosa sta succedendo qui: o la pipe o the xargssta trattando gli spazi come delimitatori tra i file. Per la mia vita, però, non riesco a capire come prevenire questo comportamento. Può essere fatto con find+ xargs? O devo usare un comando completamente diverso?

Risposte:


29

Uso

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

per esempio

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

dalla pagina man di ricerca

-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.

15

Non è necessario utilizzare xargs , perché find può eseguire comandi da solo. Nel fare ciò, non devi preoccuparti della shell che interpreta i caratteri nel nome.

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

dalla pagina man di ricerca

-exec command {} +
Questa variante dell'azione -exec esegue il comando specificato sui file selezionati, ma la riga di comando viene creata aggiungendo alla fine ciascun nome di file selezionato; il numero totale di invocazioni del comando sarà molto inferiore al numero di file corrispondenti. La riga di comando è costruita nello stesso modo in cui xargs costruisce le sue righe di comando. Nel comando è consentita solo un'istanza di `{} '. Il comando viene eseguito nella directory iniziale.


Voterei questo, ma non me ne sono andato per oggi - lo farò domani.
user9517 supporta GoFundMonica

1
@Iain - ecco qua (sono d'accordo, comunque).
Eduardo Ivanec,

Solo usando find ti perdi ancora le funzionalità di xargs, inoltre devi fare i conti con le regole di quotazione sciocche. Vedi l'argomento -P di xargs se hai più di un core / CPU.
Slartibartfast,

8

Se le versioni find e xarg sul tuo sistema non supportano -print0e -0switch (ad esempio find e xargs AIX) puoi usare questo:

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

Qui sed si occuperà di sfuggire agli spazi per gli xarg.


Questo mi ha aiutato perché avevo un lungo elenco di nomi di file che era difficile da produrre che ho usato più volte. Non posso semplicemente findripeterli tutti.
Scott M.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.