Im Grunde muss ich also eine Reihe von CSV-Dateien finden und dann mein Skript, das ich geschrieben habe, auf alle anwenden. Ich habe
find . -type f -name "*.csv" | xargs ./extractdata
das funktioniert, aber nur eine Datei und nicht alle Dateien, die ich brauche. Hilfe?
Antwort1
Der Grund, warum es nicht funktioniert hat, liegt darin, dass xargs
so viele Dateien wie möglich in eine Befehlszeile gestopft werden.
Ihr Skript "extractdata" empfängt also alle Dateien auf einmal und verarbeitet wahrscheinlich nur das erste Argument. D. h. Sie haben N Dateien, führen Sie auseinsSkript mitalledie Dateien als Argument.
Sie müssen das -n
Argument verwenden:
... | xargs -n 1 ./extractdata
Auf diese Weise haben Sie N Dateien, führen N Skripte aus miteinsjeweils ein Dateiargument.
Dies ist jedoch fast genau dasselbe wie die Ausführung find
mit der -exec
Option (ein Unterschied besteht darin, dass Sie die Dateien in der Reihenfolge verarbeiten, in der sie gefunden wurden, während Sie dies beim Piping beispielsweise nach einem Durchlauf mit sort
und/oder tun können grep
):
find ... -exec /path/to/extractdata \{\} \;
Sie können Ihr Skript möglicherweise auch parallel ausführen, indem Sie verwenden parallel
: Dadurch werden vier Instanzen gleichzeitig ausgeführt.möglicherweiseDies führt zu einer effizienteren Verarbeitung je nach Daten, RAM und Hardware:
... | parallel -n 1 -j 4 ./extractdata
(Wenn „extractdata“ temporäre Dateien mit festen Namen verwendet, was keine gute Praxis ist, dann überschreiben zwei oder mehr parallel ausgeführte Skripte gegenseitig ihre temporären Dateien und bringen so alles durcheinander.)
Antwort2
Antwort3
Es gibt mehrere Möglichkeiten, dieses Problem zu lösen. Sie können beispielsweise find
folgendermaßen darum bitten, das Skript aufzurufen:
$ find . -type f -name "*.csv" -exec your_script {} ;
{} ist der Dateiname, der jeweils gefunden wurde.
Möglicherweise müssen Sie die folgenden Zeichen maskieren:
$ find . -type f -name "*.csv" -exec your_script \{\} \;