4

我想在目录中运行一个脚本,以便为每个找到的点文件生成一个 svg 文件。就像是:

find . -name "*.dot" -exec dot -Tsvg \{} \;

这工作正常,但只是在标准输出上输出结果。通常我使用重定向来生成 svg 文件。如何获取点文件名以在重定向中使用它,例如

find . -name "*.dot" -exec dot -Tsvg > "$dotfilename".svg \{} \;
4

4 回答 4

5

您不需要输出重定向。使用 -O 保存到一个文件,该文件的名称是根据输入文件名和输出格式自动创建的。

find . -name "*.dot" -exec dot -Tsvg -O \{} \;

只是指出您可以在 -exec 的参数中多次使用 {}:

find . -name "*.dot" -exec dot -Tsvg -o \{}.svg \{} \;

第一个会从“foo.dot”产生“foo.svg”,第二个会产生“foo.dot.svg”

于 2012-07-12T14:45:44.410 回答
5

以下:

for i in `find . -name "*.dot"`; do
   dot -Tsvg $i > $i.svg
done

执行查找(在反引号中)并循环遍历结果,dot为每个结果执行。文件名在$i.

这使用反引号替换,并且是捕获命令输出以供随后在另一个命令中使用的有用机制。

要删除扩展名并添加另一个扩展名,请使用${i%.*}.svg. 有关更多信息,请参阅此 SO 答案

于 2012-07-12T14:30:16.640 回答
2

您不能在此处进行重定向。find确实使用execvp(3)或朋友执行,而不是外壳。相反,使用 shell glob,或制作一个脚本,然后您可以从中调用find

一个例子:

for i in ./*.dot
do
    svg=${i%.dot}.svg
    dot -Tsvg "$i" > "$svg"
done
于 2012-07-12T14:31:47.857 回答
2

您遇到的问题是在 find 命令之前处理了重定向。您可以通过在 -exec 调用中生成另一个 bash 进程来解决此问题。这也使得使用参数扩展删除扩展变得容易。

find . -name "*.dot" -exec bash -c 'dot -Tsvg "$1" > "${1%.*}".svg' -- {} \;
于 2012-07-12T14:36:47.027 回答