find 命令的 -exec 选项中的单独文件名和路径

find 命令的 -exec 选项中的单独文件名和路径

我正在努力逃避和表达评估。我正在尝试在find...结构内运行命令-exec COMMAND,该结构COMMAND对一个文件进行操作并输出到标准输出。要COMMAND在命令行上正常使用它,我只需重定向到一个新文件,如下所示:

COMMAND inputfilename.md > outputfilename.md.conf

这很好用。但是,如果我想递归循环全部目录及其子目录中的文件,使用find -exec,我似乎无法弄清楚如何分隔文件名和路径,以便我可以正确重定向。例如,这会产生一个错误:

find ./ *.md -not -path './/.git/*' -exec COMMAND '{} > ~/wiki/newdirectory/{}.cong' \;

因为{}扩展了整个文件路径。我尝试了basename和的各种组合dirname,但我似乎无法让它们进行评估(相反,我只是得到字符串“basename”等)。例如,这不起作用,因为文本“basename”刚刚出现

find ./ *.md -not -path './/.git/*' -exec COMMAND  '{} > ~/wiki/newdirectory/''basename {}''.conf' \;

(返回此错误:)'No such file or directory - .//newdirectory/README.md.conf > ~/wiki/newdirectory/basename .//newdirectory/README.md.conf'

任何帮助,将不胜感激。总而言之,目标是:

  1. 递归迭代*.md目录中匹配的所有文件
  2. 在每次迭代中执行相同字符串的COMMAND inputfile.md > ~/newdirectory/inputfile.md.conf地方。inputfile

谢谢!

答案1

无论您做什么,都需要调用 shell 来将命令输出重定向到一个文件,该文件的位置取决于结果find

find ./ *.md -not -path './/.git/*' -exec sh -c 'COMMAND "$0" > ~/wiki/newdirectory/"${0##*/}.cong"' {} \;

不要{}在 shell 脚本内进行替换。并非所有系统都支持此功能,即使在支持的情况下,一般情况下也不起作用,因为它将文件名视为一段 shell 语法,例如,调用的文件;rm -rf ~;.md将导致您删除所有文件。

${0##*/}使用纯字符串操作来获取文件的基本名称。您也可以使用$(basename -- "$0").

答案2

如果你find接受-execdir,这应该可行

find . -name '*.md' -not -path './/.git/*' -execdir COMMAND {} > ~/wiki/newdirectory/{}.cong \;

交替

find . -name '*.md' -not -path './/.git/*' -exec bash -c \
'for f; do COMMAND "$f" > ~/wiki/newdirectory/"${f##*/}".cong; done' _ {} +

相关内容