我想将目录中的所有文件名列出为单个参数字符串行,该行使用 Space 字符作为分隔符。
让我们考虑这个目录:
/project
├─ foo bar.c
├─ bar is not baz.c
├─ you"are"doomed
└─ baz.c
我的问题的输出是:
. "./bar is not baz.c" ./baz.c "./foo bar.c" 'you"are"doomed'
或者
. foo\ bar.c bar\ is\ not\ baz.c baz.c you\"are\"doomed
显然它不适用于空字符
\0
,因为这个字符无法在参数行上处理:
find . -print0
. foo bar.c\0bar is not baz.c\0baz.c\0you"are"doomed
我的目标是以这种方式将这些文件传递给另一个程序
program `find . | magic`
. foo\ bar.c bar\ is\ not\ baz.c baz.c you\"are\"doomed
编辑(3年后)
正如 devsolar 所指出的,我的问题是一种 XY 问题。他的解决方案允许将文件列表传递给程序。然而它并没有完全回答最初的问题。
我需要参数string的原因是我想避免为找到的每个文件执行我的
program
,因为它太慢了(尤其是在cygwin上)。
使用
xargs
也没有帮助,因为它无法转义所有字符。我最接近的解决方案是使用这个 oneliner:
find . -print0 | perl -e 'local $/="\0";print join(" ",map{s/(?=["'"'"' ])/\\/gr}<STDIN>);'
. ./bar\ is\ not\ baz.c ./baz.c ./foo\ bar.c ./haha\"haha
做
find . -exec program {} +
用于以文件名列表作为参数调用
program
。如果找到很多文件,可能会多次调用program
以避免命令行太长。
做
find . -exec program {} \;
致电
program
查找找到的 每个 文件。
是的,这确实可以正确处理文件名中的空格。
如果您可以使用其他命令,可能
find . | paste -sd " "
做你需要的事情。
在 OS X 上,需要另一个参数:
find . | paste -sd " " -
要将由换行符分隔的列表转换为由空格分隔的列表,您所需要做的就是对它们进行回显,如下所示:
echo $(find)
我也有类似的需求,需要构建一个 CSV 目录名字符串,并将其传递给
--exclude=
的 snyk monitor
参数。 我最终得到了这个调用(Alpine linux 3.17,所以使用 BusyBox find,而不是 GNU find):
snyk monitor --all-projects --exclude=$(find * -type d \( -name "*.UnitTests" -o -name "*.SystemTests" \) -exec printf '%s,' {} +)
find
的输出使用-exec
传递到printf
。每个结果都以 {}
的形式传递。 "%s,"
用逗号格式化每个项目。 你可以拥有"%s "
。
我使用
find *
而不是 find .
,因为我不希望每个目录名称前面带有 ./
此方法的唯一缺点是 last 项在输出字符串中还包含
,
这可能对你有用:
$ find -type f .| tr "\n" "\0" | xargs -0 YOUR_PROGRAM
find . -type f
:获取当前目录下的所有文件tr '\n' '\0'
:将 find 的输出转换为空分隔列表。xargs -0 YOUR_PROGRAM
使用空分隔符而不是默认的空格分隔符将该列表传递给您的程序,以便处理带有空格的文件名。这里有很多解决方案,所以我会添加另一个......
find /path -type f -printf '"%p" '
这产生:
"/path/file1" "/path/file2" "path/file 3 with spaces" ...
我终于找到了一个好的解决方案:
find . | awk '{printf "%s ", $0}'