2012-11-05 17 views
6

Vorrei passare l'elenco di output di elementi di un comando come parametro di un altro comando. Ho trovato alcune altre pagine:Uscita comando Linux come parametro di un altro comando

ma sembrano essere più complessa.

Vorrei solo copiare un file per ogni risultato di una chiamata al comando Linux find.

Cosa c'è di sbagliato qui ?:

find . -name myFile 2>&1 | cp /home/myuser/myFile $1 

Grazie

risposta

16

Questo è ciò che si vuole:

find . -name myFile -exec cp /home/myuser/myFile {} ';' 

Il dettaglio/spiegazione di questo:

  • find: invocando il comando find
  • .: iniziare ricerca dalla directory di lavoro corrente.
  • Poiché non vengono specificate le bandiere di profondità, questo cercherà in modo ricorsivo per tutte le sottocartelle
  • -name myFile: trovare i file con il nome esplicito myFile
  • -exec: per i risultati della ricerca, eseguire comandi aggiuntivi con loro
  • cp /home/myuser/myFile {}: copie /home/myuser/myFile per sovrascrivere ogni risultato restituito da find a; pensare a {} come dove ogni risultato di ricerca va.
  • ';': utilizzato per separare diversi comandi da eseguire dopo find
+0

Basta cambiare l'ordine di {} nella seconda posizione, dopo/home/myuser/myFile, e funzionerà. Grazie. –

+0

@ LuisAndrésGarcía, ah, avrei potuto fraintendermi - volevi copiare l'unico file '/ home/myuser/myFile' per sovrascrivere qualsiasi' myFile' trovato da 'find' nella cwd? –

+0

Hai ragione! :) Un altro esempio, per elencare le proprietà di qualsiasi file trovato è: find -exec ls -l {} ';' –

2

La pipa verrà inviare l'output di un programma per l'ingresso di un altro. cp non legge dal suo flusso di input sul terminale, utilizza semplicemente gli argomenti sulla riga di comando.

Si desidera utilizzare xargs con la pipe o l'argomento exec dianziché le pipe.

+2

Può fare un esempio , per favore? Grazie mille. –

3

ci sono un paio di modi per risolvere questo, a seconda se è necessario preoccuparsi di file con spazi o altri caratteri speciali nei loro nomi.

Se nessuno dei nomi di file ha spazi o caratteri speciali (sono costituiti solo da lettere, numeri, trattini e caratteri di sottolineatura), la seguente è una soluzione semplice che funzionerà. È possibile utilizzare $(command) per eseguire un comando e sostituire i risultati negli argomenti di un altro comando. La shell dividerà il risultato su spazi, tabulazioni o nuove righe e for assegnerà a turno ogni valore a $f ed eseguirà il comando su ciascun valore.

for f in $(find . -name myFile) 
do 
    cp something $f 
done 

Se si dispone di spazi o tabulazioni, è possibile utilizzare l'opzione di find -exec. Si passa -exec command args, inserendo {} dove si desidera sostituire il nome file e terminando gli argomenti con uno ;. È necessario citare lo {} e ; in modo che la shell non li interpreti.

find . -name myFile -exec cp something "{}" \; 

A volte -exec non è sufficiente. Ad esempio, in this question, volevano utilizzare l'espansione del parametro Bash per calcolare il nome file. Per fare ciò, devi passare -exec bash -c 'your command', ma poi ti capiterà di citare problemi con la sostituzione {}. Per risolvere questo problema, è possibile utilizzare -print0 da find di stampare i risultati delimitati con i caratteri nulli (che sono validi nei nomi dei file), e tubo ad un ciclo while read che divide i parametri su valori nulli:

find . -name myFile -print0 | (while read -d $'\0' f; do 
    cp something "$f" 
    done) 
Problemi correlati