Ich habe Probleme mit Escapezeichen und der Auswertung von Ausdrücken. Ich versuche, einen Befehl innerhalb einer find
...- -exec COMMAND
Struktur auszuführen, die COMMAND
auf einer Datei arbeitet und an die Standardausgabe ausgibt. Um dies COMMAND
normal auf der Befehlszeile zu verwenden, leite ich einfach zu einer neuen Datei um, wie folgt:
COMMAND inputfilename.md > outputfilename.md.conf
Das funktioniert gut. Wenn ich jedoch rekursiv überALLEdie Dateien in einem Verzeichnis und dessen Unterverzeichnis mit , find -exec
ich kann nicht herausfinden, wie ich den Dateinamen und den Pfad trennen kann, damit ich richtig umleiten kann. Dies erzeugt beispielsweise einen Fehler:
find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;
because {}
erweitert den gesamten Dateipfad. Ich habe verschiedene Kombinationen von basename
und ausprobiert dirname
, aber ich kann sie scheinbar nicht auswerten (stattdessen erhalte ich nur die Zeichenfolge „basename“ usw.). Dies hat beispielsweise nicht funktioniert, da der Text „basename“ nur
find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/''basename {}''.conf' \;
(gibt diesen Fehler zurück: 'No such file or directory - .//newdirectory/README.md.conf > ~/wiki/newdirectory/basename .//newdirectory/README.md.conf'
).
Für jede Hilfe wäre ich dankbar. Zusammenfassend ist das Ziel:
- Rekursives Durchlaufen aller passenden Dateien
*.md
in einem Verzeichnis - Ausführen
COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf
, wobeiinputfile
in jeder Iteration die gleiche Zeichenfolge vorliegt.
Danke!
Antwort1
Was auch immer Sie tun, Sie müssen eine Shell aufrufen, um die Befehlsausgabe in eine Datei umzuleiten, deren Speicherort vom find
Ergebnis abhängt.
find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND "$0" > ~/wiki/newdirectory/"${0##*/}.cong"' {} \;
Ersetzen Sie nicht {}
innerhalb des Shell-Skripts. Dies wird nicht auf allen Systemen unterstützt, und selbst wenn es unterstützt wird, würde es im Allgemeinen nicht funktionieren, da der Dateiname als Teil der Shell-Syntax behandelt würde. Beispielsweise ;rm -rf ~;.md
würde ein Dateiaufruf dazu führen, dass Sie alle Ihre Dateien löschen.
${0##*/}
verwendet reine Stringmanipulation, um den Basisnamen der Datei zu erhalten. Sie können auch verwenden $(basename -- "$0")
.
Antwort2
Wenn Sie find
akzeptieren -execdir
, sollte dies funktionieren
find . -name '*.md' -not -path './/.git/*' -execdir COMMAND {} > ~/wiki/newdirectory/{}.cong \;
Abwechselnd
find . -name '*.md' -not -path './/.git/*' -exec bash -c \
'for f; do COMMAND "$f" > ~/wiki/newdirectory/"${f##*/}".cong; done' _ {} +