Bash如何重用找到文件名?

Bash如何重用找到文件名?,bash,Bash,我想在目录中运行一个脚本,以便为每个找到的点文件生成一个svg文件。比如: find . -name "*.dot" -exec dot -Tsvg \{} \; 这很好,但只是在标准输出上输出结果。通常我使用重定向来生成svg文件。如何获取点文件名以在重定向中使用它 find . -name "*.dot" -exec dot -Tsvg > "$dotfilename".svg \{} \; 以下是: for i in `find . -name "*.dot"`; do d

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

find . -name "*.dot" -exec dot -Tsvg \{} \;
这很好,但只是在标准输出上输出结果。通常我使用重定向来生成svg文件。如何获取点文件名以在重定向中使用它

find . -name "*.dot" -exec dot -Tsvg > "$dotfilename".svg \{} \;
以下是:

for i in `find . -name "*.dot"`; do
   dot -Tsvg $i > $i.svg
done
执行查找(在倒勾中)并在结果上循环,对每个结果执行
dot
。文件名位于
$i

这使用并且是一种有用的机制,用于捕获命令输出,以便随后在另一个命令中使用


要删除扩展并添加另一个扩展,请使用
${i%.*}.svg
。有关详细信息,请参阅。

您不能在此处执行重定向
find
使用
execvp(3)
或friends执行,而不是shell。相反,可以使用shell globs,或者制作一个脚本,然后从
find

例如:

for i in ./*.dot
do
    svg=${i%.dot}.svg
    dot -Tsvg "$i" > "$svg"
done

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

find . -name "*.dot" -exec bash -c 'dot -Tsvg "$1" > "${1%.*}".svg' -- {} \;

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

find . -name "*.dot" -exec dot -Tsvg -O \{} \;
只是要指出,您可以在-exec的参数中多次使用{}:

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

第一个将从“foo.dot”生成“foo.svg”,第二个将生成“foo.dot.svg”

非常感谢。此外,从svg文件中删除.dot扩展名也很容易吗。在bash v4中有一些限制,您可以使用globstar从glob.Yah获取递归。我不想要那些废话(除了它取决于bash这一事实)。如果需要的话,我更喜欢修复我的文件组织。