Ich habe zwei Probleme. Ich versuche, Dateien als Argument durch eine Pipe zu übergeben, und ich versuche, diese Datei als Variable innerhalb der sh
Funktion zu verwenden.
Hier ist mein Befehl:
find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
Hier sucht meine Zeile nach allen Dateien, die wie " segment.something
" aussehen und übergibt sie an die rechte Seite der Pipe. In someFunction.sh
brauche ich den Namen der Datei als Argument. Nehmen wir an, die Datei wird in eingegeben segment1
.
Das someFunction.sh
druckt jede Zeile von segment1
(zum Beispiel) aus.
Wie übergebe ich die Ausgabe von der linken Seite der Pipe an die rechte Seite und wie rufe ich sie dann darin auf someFunction.sh
?
Antwort1
Ihr Befehl
$ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
hat zur Folge, dass höchstens vier Kopien des someFunction.sh
Shell-Skripts parallel gestartet werden ( -P 4
) (neue werden erstellt, sobald die alten fertig sind), wobei jede Kopie einen Dateinamen als Argument erhält ( -n 1
).
Das bedeutet, dass jeder Aufruf Ihres Skripts wie folgt aussieht:
sh someFunction.sh segmentsomething
Innerhalb des Skripts fügt die Shell die Werte derPositionsparameter(die Argumente in der Befehlszeile) in $1
usw. $2
( $0
enthält normalerweise den Namen des Skripts selbst). In Ihrem Fall $1
enthält den Namen der Datei und die anderen sind leer.
Also, im Skript:
filename="$1"
echo "$filename"
cat "$filename"
Das ist alles. Wenn man find
nach Dateien sucht und ihre Dateinamen weitergibt, xargs
gibt es normalerweise das Problem mit den fehlerhaften Dateinamen, an die sich die Leute gegenseitig erinnern, und das werde ich hier auch tun.
Das find
Dienstprogramm übergibt Dateinamen, die durch Leerzeichen getrennt sind. Das ist nicht sinnvoll, wenn Ihre Dateinamen Leerzeichen enthalten, da dies zu Problemen beim xargs
Aufrufen Ihres Skripts mit richtigen Namen führen würde.
Daher ist es eine gute Praxis,stetsVerwenden Sie -print0
mit find
und -0
mit xargs
, was bedeutet, dass die Dateinamen nicht durch Leerzeichen, sondern durch nul
Zeichen ( \0
) getrennt werden. Dies macht es viel sicherer.
Daher:
$ find . -name 'segment*' -print0 | xargs -0 -n1 -P4 sh someFunction.sh
Antwort2
Sie könnten so etwas verwenden, vorausgesetzt, someFunction.sh
es befindet sich in Ihrem Arbeitsverzeichnis.
find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh
Die -print0
und -0
erlauben Dateien mit Leerzeichen im Namen (ein häufiges Problem). In meinem someFunction.sh
habe ich
#!/bin/bash
echo "Arg: " $1
cat $1
Das gibt einfach den Dateinamen aus und schreibt dann den Inhalt der übergebenen Datei ansomeFunction.sh