xargs -I sostituiscono l'opzione differenza-str


16

Secondo la mia comprensione, quanto segue dovrebbe significare esattamente lo stesso:

ls -1 | xargs file {}
ls -1 | xargs -I{} file {}

se l'opzione -I non è specificata, è predefinita -I {}.

Voglio elencare tutti i file nella directory corrente ed eseguire il filecomando su ciascuno di essi. Alcuni hanno spazi nei loro nomi. Tuttavia, ho notato la differenza. Vedi sotto:

$ ls -1
Hello World
$ ls -1 | xargs file {}
{}:    ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory

Con -I {} esplicitamente specificato, gli spazi vuoti nei nomi dei file vengono trattati come previsto.


3
"Se l'opzione -I non è specificata, è predefinito -I {}" - questo è errato, almeno con xargs GNU.
Jjlin,

Capisco il mio errore. Dovrei specificare xargs fileo xargs -I{} file {}. Non dovrei essere xargs file {}. Immagino che quando si specifica esplicitamente -I {}, la bash lo tratterà come file "Hello World". Senza -I {}, viene trattato come file Hello World.
foresightyj

1
(1) Questa discussione ha poco a che fare con la shell (bash). (2) È utile conoscere l' -1opzione ls, ma è attivo per impostazione predefinita quando l'output di lsè un file o una pipe, quindi non è necessario qui. (3) Stai confondendo -Icon l' opzione deprecata -i(minuscola I). -ifooè equivalente a -Ifoo, ma plain -iè equivalente a -I{}. Ma usa -I{}. (4) Se vuoi davvero fare quello che dici di voler fare, perché non dire semplicemente file *?
Scott,

@Scott Il mio intento originale era quello di scrivere `find. -name "* .mov" | xargs -I {} file {} `per trovare tutti i file mov in modo ricorsivo ed eseguirli file. Ma ho trovato un esempio più semplice usando ls. Hai ragione. Per quello, file *è il migliore.
foresightyj

1
find ha -exec.
Cristian Ciupitu,

Risposte:


20

Il -Irichiede un segnaposto definito. L' -iopzione supporrà {}sia il segnaposto. Qui è stato trovato il presupposto di {} man xargsalmeno su Cygwin e CentOS.

xargs chiamato senza entrambe le opzioni non ha bisogno del segnaposto e aggiunge semplicemente STDIN alla fine degli argomenti.

Aggiungi echoai tuoi esempi per vedere cosa sta facendo xargs:

$ ls -1
Hello World/

Il tuo esempio erroneamente usa {}:

$ ls -1 | xargs echo file {}
file {} Hello World/

così il filecmd vede argomenti {} Hello Worlded errori.

Se vuoi usare esplicitamente {}nella tua chiamata xargs:

$ ls -1 | xargs -i echo file {}
file Hello World/

O senza segnaposto:

$ ls -1 | xargs echo file
file Hello World/

xargs come chiamato sopra non ha bisogno di {}. Aggiunge STDIN alla fine del comando senza segnaposto. L'uso di {} di solito significa che vuoi eseguire STDIN da qualche parte nel mezzo del cmd, come in:

$ ls -1 | xargs -i mv {} /path/to/someplace/.

Questo è molto chiaro Anche se la tua risposta è un po 'in ritardo, ma leggerla rafforza davvero la mia comprensione.
previsione del
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.