
Ich habe eine Reihe von Markdown-Dateien in meinem Ordner, die ich mit Pandoc in HTML konvertieren möchte.
Der Befehl, den ich normalerweise verwende, ist
pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html
wobei Atten.md
der Name einer typischen Markdown-Datei ist. Ich möchte jedoch alle Dateien durchlaufen und .md wie oben beschrieben in .html konvertieren. Wie mache ich das in Bash oder Zsh?
Antwort1
Mit find
:
find path/to/dir -name "*.md" -type f -exec sh -c '
pandoc -f markdown -t html --css pandoc.css -o "${1%.*}.html" "$1"
' find-sh {} \;
Es sollte in Bash, Zsh und vielen anderen Shells funktionieren. Die einzige Aufgabe der äußeren Shell besteht darin, find
mit den richtigen Argumenten ausgeführt zu werden.
Diese Version startet einen einzelnen Prozess, sh
um so viele Dateien wie möglich zu verarbeiten ( sh
bei Bedarf werden weitere Prozesse gestartet):
find path/to/dir -name "*.md" -type f -exec sh -c '
for f; do
pandoc -f markdown -t html --css pandoc.css -o "${f%.*}.html" "$f"
done
' find-sh {} +
Anmerkungen:
- Die innere Shell wird nur aufgerufen, weil wir die alte Erweiterung entfernen müssen. Wenn dies nicht erforderlich wäre,
… -exec pandoc … -o {}.html {} \;
würde wahrscheinlich eine Lösung mit funktionieren. „Wahrscheinlich“, weil POSIX erfordert, nurfind
ein einziges zu ersetzen{}
. Es ist eine „Gefälligkeit“ derfind
von Ihnen verwendeten Implementierung, wenn etwas anderes ersetzt wird (wie{}.html
oder das zweite Auftreten von{}
). -execdir
anstelle von-exec
wäre besser, aber es ist nicht POSIX.-execdir
./"$1"
würde es uns erlauben , statt"$1"
(bzw../"$f"
statt ) zu verwenden , um zu verhindern, dass es von als Option"$f"
interpretiert wird . Ein anderer Ansatz istpandoc
--
aber ich weiß nicht, obpandoc
es das unterstützt. Ich denke, in Ihrem Fall"$1"
kann es nicht auf irgendetwas erweitert werden, das mit beginnt,-
weil es mit beginnen musspath/to/dir
, und wennpath/to/dir
es mit beginnt-
, würde es vonfind
vornherein durch falsch interpretiert werden. Generell ist diese Sorge jedoch berechtigt.Beim
pandoc
Aufruf habe ich den Operanden nur deshalb ans Ende verschoben, weil ich die gebräuchlichste Reihenfolge bevorzugecommand -options operands
.Die Lösung ist rekursiv. Um sie nicht-rekursiv zu machen, geben Sie an
-maxdepth 1
. Wenn Ihrfind
das nicht unterstützt,-maxdepth
dann studieren SieDasoder löschen Sie esfind
und lassen Sie die äußere Shell über die Dateien iterieren:# written for Bash ( cd path/to/dir || exit 125 for f in ./*.md ./.*.md; do [ -f "$f" ] && pandoc -f markdown -t html --css pandoc.css -o "${f%.*}.html" "$f" done )
Spezifische Hinweise zum obigen Code:
- Die Untershell dient dazu,
cd
zu arbeiten, ohne die aktuelle Shell zu beeinträchtigen. - Wenn
cd
dies aus irgendeinem Grund fehlschlägt, wird der Rest nicht ausgeführt. Dies ist eine gute Vorgehensweise. ./*.md
anstelle von plain*.md
verhindert"$f"
, dass es später als Option interpretiert wird../.*.md
wird hinzugefügt, da./*.md
es nicht mit den Dotfiles übereinstimmt.[ -f "$f" ]
ist zu verhindern- Aufrufen
pandoc
von Verzeichnissen, speziellen Dateien und dergleichen; - Aufruf
pandoc
für „nonexistent“./*.md
(oder./.*.md
), wenn nichts dem Muster entspricht.
- Aufrufen
Zsh ist etwas anders. Der Code sollte jedoch funktionieren
sh
und da eine Subshell sowieso nützlich ist, würde es keinen großen Unterschied machen, wenn Siesh
explizit von einer beliebigen vernünftigen Shell aus aufrufen würden:sh -c 'cd path/to/dir || exit 125 for … done '
- Die Untershell dient dazu,
Antwort2
Sie sollten find
und seine verwenden -exec
(sieheMann finden):
find YourDirectory -name \*.md | \
while IFS= read fn; do \
pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done
Oder vielleicht -execdir
.
Antwort3
Sie können die Datei mit einem for iterieren:
for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done