2012-11-05 11 views
6

Ich möchte die Ausgabeliste von Elementen eines Befehls als Parameter eines anderen Befehls übergeben. Ich habe einige andere Seiten gefunden:Linux-Befehlsausgabe als Parameter eines anderen Befehls

aber sie scheinen komplexer zu sein.

Ich möchte nur eine Datei in jedes Ergebnis eines Aufrufs des Linux-Befehls find kopieren.

Was ist hier falsch ?:

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

Dank

Antwort

16

Dies ist, was Sie wollen:

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

Eine Aufschlüsselung/Erklärung hierfür:

  • find: Suche starten von aktuellen Arbeitsverzeichnis:
  • . den Befehl find aufrufen.
  • Da keine Tiefe Flags angegeben werden, wird dies für alle Unterordner rekursiv suchen
  • -name myFile: Finden Sie Dateien mit dem expliziten Namen myFile
  • -exec: für die Suchergebnisse, führen zusätzliche Befehle mit ihnen
  • cp /home/myuser/myFile {}: Kopien /home/myuser/myFile, um jedes von find zurückgegebene Ergebnis zu überschreiben; denke an {} als wo jedes Suchergebnis geht.
  • ';': verwendet, um verschiedene Befehle zu trennen, nachdem dieses Problem zu lösen, je nachdem, ob Sie brauchen, um Sorgen über Dateien mit Leerzeichen oder anderen Sonderzeichen im Namen find
+0

Ändern Sie einfach die Reihenfolge von {} in die zweite Position nach/home/myuser/myFile, und es funktioniert. Vielen Dank. –

+0

@ LuisAndrésGarcía, ah, ich könnte dich missverstanden haben - du wolltest die eine Datei '/ home/myuser/myFile' kopieren, um' myFile' zu ​​ersetzen, die durch 'find' in der cwd gefunden wurden? –

+0

Sie haben Recht! :) Ein weiteres Beispiel, um die Eigenschaften einer gefundenen Datei aufzulisten, ist: find -exec ls -l {} ';' –

2

Das Rohr wird die Ausgabe eines Programms mit dem Eingang des anderen schicken. cp liest nicht aus seinem Eingabestrom am Terminal, es verwendet nur die Argumente in der Befehlszeile.

Sie wollen entweder xargs mit dem Rohr verwenden oder find ‚s exec Argumente anstelle von Rohren.

+2

Können Sie ein Beispiel geben , Bitte? Vielen Dank. –

3

Es gibt ein paar Möglichkeiten, ausgeführt werden sollte.

Wenn keiner der Dateinamen Leerzeichen oder Sonderzeichen hat (sie bestehen nur aus Buchstaben, Zahlen, Bindestrichen und Unterstrichen), dann ist das Folgende eine einfache Lösung, die funktioniert. Sie können $(command) verwenden, um einen Befehl auszuführen, und die Ergebnisse in die Argumente eines anderen Befehls einfügen. Die Shell teilt das Ergebnis in Leerzeichen, Tabulatoren oder Zeilenumbrüche auf, und for weist der Reihe nach jeden Wert $f zu und führt den Befehl für jeden Wert aus.

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

Wenn Sie Leerzeichen oder Tabs tun, könnten Sie -exec Option der Fund verwenden. Sie übergeben -exec command args, setzen {}, wo der Dateiname ersetzt werden soll, und beenden Sie die Argumente mit einer ;. Sie müssen die {} und ; angeben, damit die Shell sie nicht interpretiert.

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

Manchmal reicht -exec nicht aus. Zum Beispiel wollten sie in this question die Bash-Parametererweiterung verwenden, um den Dateinamen zu berechnen. Um dies zu tun, müssen Sie -exec bash -c 'your command' übergeben, aber dann werden Sie mit der {} Ersetzung Probleme auftreten. Um dies zu lösen, können Sie -print0 von find verwenden, um die Ergebnisse zu drucken, mit Null-Zeichen begrenzt (die in Dateinamen ungültig sind), und eine Pipe an eine while read Schleife, die Parameter auf NULL-Wert teilt:

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