我正在努力逃避和表达评估。我正在尝试在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'
。
任何帮助,将不胜感激。总而言之,目标是:
- 递归迭代
*.md
目录中匹配的所有文件 - 在每次迭代中执行相同字符串的
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' _ {} +