我有一个程序需要文件路径作为参数,该参数不能被引用并且不能依赖于工作目录。这可以在不链接多个xargs
, tr
, find
, s 的情况下完成吗readlink
?
“*.csv”文件的输出示例:/home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
答案1
为了将文件路径作为参数传递给命令,find
自己做这件事-exec
选项没有任何xargs
诡计:
find /home/user -name '*.csv' -exec yourcommand '{}' +
这将找到调用的每个文件*.csv
,/home/user
然后yourcommand /home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv ...
将所有找到的文件作为参数执行。找到的每个文件都作为单独的完整参数传递给程序,因此不需要转义或其他任何内容:yourcommand
获取许多参数,每个参数都是完整的文件路径。
另一种方法是一些 shell (zsh
尤其)支持更高级的通配符,您可以在其中编写:
yourcommand **/*.csv
也能得到上面的效果。
如果您确实想要转义字符串本身,而不是直接运行命令,您可以使用bash
's内置printf
:
find /home/user -name '*.csv' -exec bash -c 'printf "%q " "$@"' dummy '{}' +
格式%q
规范扩展为字符串参数的 shell 转义版本。对于许多参数,printf
会重复所有参数的格式字符串,因此这会生成命令的所有参数的以空格结尾的转义字符串bash -c
。dummy
用作 的值$0
,并"$@"
给出printf
所有其余参数,即您的(完整)文件名。对于您的示例,这将准确输出/home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
.
答案2
和zsh
:
print -r -- **/*.csv(D:a:q)
请注意,某些字符(如换行符、制表符或不可打印的字符)是用符号呈现的,$'...'
这对您来说可能是个问题。
另一种方法是:
print -r -- *.csv(e/'REPLY=${(qq)REPLY:a}'/)
其中所有文件路径都用单引号引起来。