我的文件夹中有一堆 markdown 文件,我想使用 pandoc 将其转换为 html。
我通常使用的命令是
pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html
其中Atten.md
是典型 markdown 文件的名称。但是,我想遍历所有文件并像上面那样将 .md 转换为 .html。如何在 bash 或 zsh 中执行此操作?
答案1
和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 {} \;
它应该可以在 Bash、Zsh 和许多其他 shell 中工作。外壳的唯一工作是使用find
适当的参数运行。
此版本生成一个单一进程sh
来处理尽可能多的文件(sh
如果需要,将生成更多进程):
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 {} +
笔记:
- 调用内壳只是因为我们需要删除旧扩展。如果这不是要求,那么使用 的解决方案
… -exec pandoc … -o {}.html {} \;
可能会奏效。“可能”是因为 POSIX 需要find
替换唯一的。如果替换了其他内容(例如或 的第二次出现),则这是您使用的实现{}
的“礼节” 。find
{}.html
{}
-execdir
而不是-exec
会更好但它不是 POSIX。-execdir
允许我们使用./"$1"
代替"$1"
(分别是:./"$f"
代替"$f"
)来防止它被解释为pandoc
选项。另一种方法是--
但我不知道是否pandoc
支持它。我认为在你的情况下"$1"
不能扩展到以 开头的任何内容,-
因为它必须以 开头path/to/dir
,如果path/to/dir
以 开头,那么它首先-
会被误解。但总的来说,这种担忧是合理的。find
在
pandoc
调用时我将操作数移到末尾只是因为我喜欢最常见的顺序command -options operands
。该解决方案是递归的。要使其非递归,请指定
-maxdepth 1
。如果您find
不支持,-maxdepth
请研究这或者删除find
并让外壳迭代文件:# 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 )
针对上述代码的具体注释:
- 子 shell 的
cd
作用是不影响当前 shell 的。 - 如果
cd
因任何原因失败,则其余部分将不会被执行。这是一个很好的做法。 ./*.md
而不是简单的*.md
防止"$f"
稍后被解释为选项。./.*.md
./*.md
由于与点文件不匹配而被添加。[ -f "$f" ]
是为了防止- 调用
pandoc
目录、特殊文件等; - 当没有任何东西与模式匹配时,调用
pandoc
不存在./*.md
(或)。./.*.md
- 调用
Zsh 稍有不同。不过代码应该可以工作,而且因为子 shell 无论如何都是有用的,所以如果你从任何正常的 shell 中显式
sh
调用,也不会有太大区别:sh
sh -c 'cd path/to/dir || exit 125 for … done '
- 子 shell 的
答案2
您应该使用find
及其-exec
(参见男人找到):
find YourDirectory -name \*.md | \
while IFS= read fn; do \
pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done
或者可能-execdir
。
答案3
您可以使用 for 来迭代该文件:
for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done