Bash 查找和删除文件的最快方法是什么?

Bash 查找和删除文件的最快方法是什么?,bash,find-util,Bash,Find Util,与: 如果找到文件foo bar.txt,则不会将其与du一起计数或删除该文件。跳出空格的最佳方法是什么?也许find/-name'*.txt'-exec du-hc{}更像您要找的东西吗 但是,像您这样做,您在对du的调用中缺少引号,并且在它不起作用时不必要地使用xargs。您似乎迷恋echo,他不是您的朋友 由于文件名中不允许使用\0,因此可以使用-print0选项从查找安全地收集结果: Find="$(find / -name "*.txt" )" du -hc "$Find" | tai

与:


如果找到文件
foo bar.txt
,则不会将其与du一起计数或删除该文件。跳出空格的最佳方法是什么?

也许
find/-name'*.txt'-exec du-hc{}
更像您要找的东西吗

但是,像您这样做,您在对
du
的调用中缺少引号,并且在它不起作用时不必要地使用
xargs
。您似乎迷恋
echo
,他不是您的朋友

由于文件名中不允许使用
\0
,因此可以使用
-print0
选项从
查找
安全地收集结果:

Find="$(find / -name "*.txt" )"
du -hc "$Find" | tail -n1
echo "$Find" | xargs rm -r

“更正”现在应该可以在MacOS和Linux上使用。

如果您的任何文件名都不能嵌入换行符(这很不寻常),您可以使用以下选项:

注意:为了防止在试验这些命令时意外删除文件,我将
/
替换为输入目录。(如问题中所用)使用
/foo

按照指令,使用
+
终止传递给
-exec
的命令至关重要
find
将单个命令行中的匹配项传递给目标命令;通常,但不一定,这会导致一次调用;有效地
-exec+
类似于内置的
xargs
,不同的是参数中嵌入的空格并不重要


换句话说:
-exec+
不仅比管道传输到
xargs
更健壮,而且由于不需要管道和另一个实用程序,因此效率也更高。

IFS
设置为换行符,这样变量扩展中的空格就不会被用作字分隔符。
查找-delete
最快@Cyrus:谢谢你清理了其他注释,但是如果你想保留shellcheck.net注释,请重新创建它,声明它不再直接适用,并且你只是建议shellcheck.net作为一个通常有用的资源……通常,“转义”数据中的空格或其他内容(与代码相反)这是错误的事情:如果你为了防止解析而转义它们,这意味着你正在通过解析器运行数据,而最佳实践方法根本不这样做……这与试图转义进入SQL的值是错误的事情,而不是将它们传递到带外的正确实践几乎是一样的(即通过绑定参数)。要使
du-hc
按预期工作(报告总大小),必须将所有文件名传递给它;因此:
-exec du-hc{}+
。您的循环解决方案除了效率低下之外,还有同样的问题:对单个文件调用
du-hc
不是OP想要的。而且,您可能忘记了在
rm
命令之前删除
xargs
。对,剪切-粘贴错误。而且……是的,我可以用任何一种方式解释意图,只要
du
rm-r
也让我感到困惑……除非有人有名为*.txt?Re
rm-r
的目录:确实很奇怪;至于
du
:从OP自己的解决方案尝试中,我很明显,其目的是汇总所有文件大小并报告总大小(字节计数)。我同意嵌入的换行符很少见,但面对它们,这种方法有什么脆弱之处?目标是否与POSIX find兼容?@CharlesDuffy:独立的
find
命令避免了嵌入的换行符问题,这一点在您对该问题的有益评论中得到了建议(虽然不能保证一次调用
du
)。否则,这是在方便性/效率和覆盖所有边缘情况之间的折衷。您能想出一种完全可靠的方法来收集所有文件名,而不需要循环和临时文件吗?
 date > /private/var/mobile/Documents/Local\ Cookies/Clean

 find . -print0 | while IFS='' read -r -d '' file
 do
      du -hc "$file" | tail -n 1
      rm "$file"
 done
# Read all filenames into a Bash array; embedded spaces in
# filenames are handled correctly.
IFS=$'\n' read -d '' -ra files < <(find /foo -name "*.txt")

# Run the `du` command:
du -hc "${files[@]}" | tail -1

# Delete the files.
rm -r "${files[@]}"
# The `du` command
find /foo -name "*.txt" -exec du -hc {} + | tail -n1

# Deletion.
# Note that both GNU and BSD `find` support the `-delete` primary,
# which supports deleting both files and directories.
# However, `-delete` is not POSIX-compliant (a POSIX-compliant alternative is to
# use `-exec rm -r {} +`).
find /foo -name "*.txt" -delete