我想通过管道将文件名传递给其他程序,但是当名称包含空格时,它们都会阻塞。
假设我有一个名为的文件。
foo bar
Run Code Online (Sandbox Code Playgroud)
我怎样才能find返回正确的名字?
显然我想要:
foo\ bar
Run Code Online (Sandbox Code Playgroud)
或者:
"foo bar"
Run Code Online (Sandbox Code Playgroud)
编辑:我不想通过xargs,我想得到一个格式正确的字符串,find以便我可以将文件名字符串直接传送到另一个程序。
cuo*_*glm 25
POSIXLY:
find . -type f -exec sh -c '
for f do
: command "$f"
done
' sh {} +
Run Code Online (Sandbox Code Playgroud)
有find支持-print0和xargs支持-0:
find . -type f -print0 | xargs -0 <command>
Run Code Online (Sandbox Code Playgroud)
-0 选项告诉 xargs 使用 ASCII NUL 字符而不是空格来结束(分隔)文件名。
例子:
find . -maxdepth 1 -type f -print0 | xargs -0 ls -l
Run Code Online (Sandbox Code Playgroud)
evi*_*oup 12
使用-print0是一种选择,但并非所有程序都支持使用空字节分隔的数据流,因此您必须在某些事情上使用xargs该-0选项,正如 Gnouc 的回答所述。
另一种方法是使用find's-exec或-execdiroptions。以下第一个将somecommand一次提供一个文件名,而第二个将扩展为文件列表:
find . -type f -exec somecommand '{}' \;
find . -type f -exec somecommand '{}' +
Run Code Online (Sandbox Code Playgroud)
您可能会发现在许多情况下最好使用通配符。如果您有现代 shell(bash 4+、zsh、ksh),您可以使用globstar( **) 进行递归全局匹配。在 bash 中,您必须设置:
shopt -s globstar
somecommand ./**/*.txt ## feeds all *.txt files to somecommand, recursively
Run Code Online (Sandbox Code Playgroud)
我的shopt -s globstar extglob.bashrc 中有一行说,所以我总是启用它(扩展的 globs 也是如此,它们也很有用)。
如果您不想要递归,显然只是使用./*.txt,以使用工作目录中的每个 *.txt。find具有一些非常有用的细粒度搜索功能,并且对于数以万计的文件是必需的(此时您将遇到 shell 的最大参数数量),但对于日常使用而言,它通常是不必要的。
myk*_*hal 11
因此,如果您不想使用xargs(因此可能也不想使用parallel),find可以按以下方式逐行读取和处理输出:
find . -type f | while read x; do
# do something with $x
done
Run Code Online (Sandbox Code Playgroud)
小智 5
find ./ | grep " "
Run Code Online (Sandbox Code Playgroud)
会得到包含空格的文件和目录
find ./ -type f | grep " "
Run Code Online (Sandbox Code Playgroud)
会让你的文件包含空格
find ./ -type d | grep " "
Run Code Online (Sandbox Code Playgroud)
会让你的目录包含空格
| 归档时间: |
|
| 查看次数: |
72447 次 |
| 最近记录: |