Trennen Sie Dateinamen und Pfad innerhalb der Option -exec des Find-Befehls

Trennen Sie Dateinamen und Pfad innerhalb der Option -exec des Find-Befehls

Ich habe Probleme mit Escapezeichen und der Auswertung von Ausdrücken. Ich versuche, einen Befehl innerhalb einer find...- -exec COMMANDStruktur auszuführen, die COMMANDauf einer Datei arbeitet und an die Standardausgabe ausgibt. Um dies COMMANDnormal 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 -execich 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 basenameund 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:

  1. Rekursives Durchlaufen aller passenden Dateien *.mdin einem Verzeichnis
  2. Ausführen COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf, wobei inputfilein 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 findErgebnis 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 ~;.mdwü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 findakzeptieren -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' _ {} +

verwandte Informationen