我在UNIX的一个目录下有几百个PDF。PDF的名称非常长(约60个字符)。

当我尝试使用以下命令一起删除所有PDF时:

rm -f *.pdf

我收到以下错误:

/bin/rm: cannot execute [Argument list too long]

此错误的解决方案是什么?mv和cp命令是否也会出现此错误?如果是,如何解决这些命令?


当前回答

如果你想删除30/90天以上(+)或30/90天以下(-)的文件/文件夹,可以使用以下ex命令

例如:对于删除90天文件/文件夹后的90天不包括上述内容,这意味着91、92……100天

find <path> -type f -mtime +90 -exec rm -rf {} \;

例如:对于您想要删除的最近30天的文件,请使用以下命令(-)

find <path> -type f -mtime -30 -exec rm -rf {} \;

如果你想保存文件超过2天

find <path> -type f -mtime +2 -exec gzip {} \;

如果您只想查看过去一个月的文件/文件夹。前任:

find <path> -type f -mtime -30 -exec ls -lrt {} \;

30天以上,然后列出文件/文件夹前任:

find <path> -type f -mtime +30 -exec ls -lrt {} \;

find /opt/app/logs -type f -mtime +30 -exec ls -lrt {} \;

其他回答

rm命令对可以同时删除的文件有限制。

一种可能性是,您可以根据文件模式多次使用rm命令删除它们,例如:

rm -f A*.pdf
rm -f B*.pdf
rm -f C*.pdf
...
rm -f *.pdf

也可以通过find命令删除它们:

find . -name "*.pdf" -exec rm {} \;

之所以出现这种情况,是因为bash实际上将星号扩展到每个匹配的文件,从而产生一个非常长的命令行。

试试看:

find . -name "*.pdf" -print0 | xargs -0 rm

警告:这是一个递归搜索,也会在子目录中查找(和删除)文件。只有当您确定不需要确认时,才在rm命令中使用-f。

可以执行以下操作以使命令非递归:

find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

另一个选项是使用find的-delete标志:

find . -name "*.pdf" -delete

你可以试试这个:

for f in *.pdf
do
  rm "$f"
done

编辑:ThiefMaster的评论建议我不要向年轻的壳牌公司的绝地武士透露这种危险的做法,所以我会添加一个更“安全”的版本(为了在有人拥有“-rf…pdf”文件时保存东西)

echo "# Whooooo" > /tmp/dummy.sh
for f in '*.pdf'
do
   echo "rm -i \"$f\""
done >> /tmp/dummy.sh

运行以上步骤后,只需在您喜爱的编辑器中打开/tmp/ddumy.sh文件,并检查每一行是否有危险的文件名,如果发现,请将其注释掉。

然后在工作目录中复制dummy.sh脚本并运行它。

所有这些都是出于安全考虑。

tl;博士

这是命令行参数大小的内核限制。请改用for循环。

问题的根源

这是一个系统问题,与execve和ARG_MAX常量有关。有很多关于这方面的文档(参见man execve、debian的wiki、ARG_MAX详细信息)。

基本上,扩展生成的命令(及其参数)超过ARG_MAX限制。在内核2.6.23中,限制设置为128 kB。此常数已增加,您可以通过执行以下操作获取其值:

getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic

解决方案:使用for循环

按照BashFAQ/095上的建议使用for循环,除了RAM/内存空间之外没有其他限制:

试运行以确定它将删除您期望的内容:

for f in *.pdf; do echo rm "$f"; done

并执行它:

for f in *.pdf; do rm "$f"; done

这也是一种可移植的方法,因为glob在shell之间具有强大且一致的行为(POSIX规范的一部分)。

注意:正如几条评论所指出的,这确实较慢,但更易于维护,因为它可以适应更复杂的场景,例如,一个人要做的不止一个动作。

解决方案:使用find

如果您坚持,您可以使用find,但实际上不要使用xargs,因为它“在读取非NUL分隔的输入时很危险(损坏、可利用等)”:

find . -maxdepth 1 -name '*.pdf' -delete 

使用-maxdepth 1-delete而不是-exec rm{}+允许find在不使用外部进程的情况下简单地执行所需的系统调用,因此速度更快(多亏了@chepner注释)。

工具书类

我得到了“参数列表太长”。如何处理大块列表?@羊毛边的execve(2)-Linux手册页(搜索ARG_MAX);错误:参数列表太长@Debian的wiki;为什么在传递带引号的参数时会得到“/bin/sh:参数列表太长”?@超级用户

要删除前100个文件:

rm-rf'ls|头部-100'