smilingbuddha Asked: 2019-09-30 21:11:40 +0800 CST2019-09-30 21:11:40 +0800 CST 2019-09-30 21:11:40 +0800 CST 使用 bash 遍历文件夹中的所有文件 772 我的文件夹中有一堆降价文件,我想用 pandoc 将它们转换为 html。 我通常使用的命令是 pandoc Atten.md -f markdown -t html --css pandoc.css -o Atten.html 其中Atten.md是典型的降价文件的名称。但是,我想遍历所有文件并将 .md 转换为 .html ,如上所述。我如何在 bash 或 zsh 中做到这一点? bash zsh 3 个回答 Voted Best Answer Kamil Maciorowski 2019-10-02T00:11:12+08:002019-10-02T00:11:12+08:00 与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而不是 plain*.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 ' uzsolt 2019-10-01T00:54:33+08:002019-10-01T00:54:33+08:00 你应该使用find和它的-exec(见man find): find YourDirectory -name \*.md | \ while IFS= read fn; do \ pandoc ${fn} -f markdown -t html --css pandoc.css -o ${fn%.md}.html ; done 或者也许-execdir。 alessiosavi 2019-09-30T22:28:14+08:002019-09-30T22:28:14+08:00 您可以使用 for 迭代文件: for item in *.md; do CONVERT_FILE_COMMAND $item "$(basename '$item' .md).html; done
与
find
:它应该在 Bash、Zsh 和许多其他 shell 中工作。外壳的唯一工作是
find
使用正确的参数运行。此版本生成一个
sh
以处理尽可能多的文件(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
并让外壳迭代文件:特定于上述代码的注释:
cd
在不影响当前shell 的情况下工作。cd
由于某种原因失败,那么其余的将不会被执行。这是一个很好的做法。./*.md
而不是 plain*.md
可以防止"$f"
以后被解释为一个选项。./.*.md
添加是因为./*.md
不匹配点文件。[ -f "$f" ]
是为了防止pandoc
目录、特殊文件等;pandoc
不存在的./*.md
(或)。./.*.md
Zsh 有点不同。代码应该可以工作,因为子shell无论如何都是有用的,所以如果你从任何理智的shell显式
sh
调用它不会有太大的区别:sh
你应该使用
find
和它的-exec
(见man find):或者也许
-execdir
。您可以使用 for 迭代文件: