import os
filedir = '/tmp/' #The directory you wish to run rm on
filelist = (os.listdir(filedir)) #gets listing of all files in the specified dir
newlist = [] #Makes a blank list named newlist
for i in filelist:
if str((i)[:4]) not in newlist: #This makes sure that the elements are unique for newlist
newlist.append((i)[:4]) #This takes only the first 4 charcters of the folder/filename and appends it to newlist
for i in newlist:
if 'tmp' in i: #If statment to look for tmp in the filename/dirname
print ('Running command rm -rf '+str(filedir)+str(i)+'* : File Count: '+str(len(os.listdir(filedir)))) #Prints the command to be run and a total file count
os.system('rm -rf '+str(filedir)+str(i)+'*') #Actual shell command
print ('DONE')
# delete files
import os as os
import glob
import multiprocessing as mp
directory = r'your/directory'
os.chdir(directory)
files_names = [i for i in glob.glob('*.{}'.format('pdf'))]
# report errors from pool
def callback_error(result):
print('error', result)
# delete file using system command
def delete_files(file_name):
os.system('rm -rf ' + file_name)
pool = mp.Pool(12)
# or use pool = mp.Pool(mp.cpu_count())
if __name__ == '__main__':
for file_name in files_names:
print(file_name)
pool.apply_async(delete_files,[file_name], error_callback=callback_error)
30 回答
如果在删除大量文件时需要保留服务器或系统 responsive ,则每个删除语句之间的
sleep
可能是一个很好的方法 .rm命令具有可以同时删除的文件的限制 .
您可以使用多次rm命令删除它们的一种可能性是基于您的文件模式,例如:
您也可以通过find命令删除它们:
发生这种情况的原因是因为bash实际上将星号扩展到每个匹配的文件,从而产生一个非常长的命令行 .
试试这个:
Warning: 这是一个递归搜索,也会在子目录中找到(和删除)文件 . 只有在您确定不需要确认时,才能将
-f
添加到rm命令 .您可以执行以下操作以使命令非递归:
另一种选择是使用find的
-delete
标志:tl;博士
这是对命令行参数大小的内核限制 . 请改用
for
循环 .问题的根源
这是一个系统问题,与
execve
和ARG_MAX
常量有关 . 有大量关于此的文档(参见man execve,debian's wiki) .基本上,扩展产生的命令(及其参数)超过了
ARG_MAX
限制 . 在内核2.6.23
上,限制设置为128 kB
. 这个常量已经增加,你可以通过执行以下方法获得它的值:解决方案:使用for循环
在BashFAQ/095上建议使用
for
循环,除RAM /内存空间外没有限制:这也是一种可移植的方法,因为glob在shell中具有强大且一致的行为(part of POSIX spec) .
Note: 正如几条评论所指出的那样,这确实更慢但更易于维护,因为它可以适应更复杂的情况,例如:人们想要做的不仅仅是一个动作 .
解决方案:使用find
如果你坚持,你可以使用
find
但真的 don't use xargs ,因为它"is dangerous (broken, exploitable, etc.) when reading non-NUL-delimited input":使用
-maxdepth 1 ... -delete
而不是-exec rm {} +
允许find
在不使用外部进程的情况下简单地执行所需的系统调用,因此更快(感谢@chepner comment) .参考文献
I'm getting "Argument list too long". How can I process a large list in chunks? @ wooledge
execve(2) - Linux man page(搜索ARG_MAX);
Error: Argument list too long @ Debian的wiki;
Why do I get “/bin/sh: Argument list too long” when passing quoted arguments? @SuperUser
find
有一个-delete
动作:另一个答案是强制
xargs
批量处理命令 . 比如delete
文件100
一次,cd
进入目录并运行:echo *.pdf | xargs -n 100 rm
或者您可以尝试:
你可以试试这个:
编辑:ThiefMaster评论建议我不要向年轻的shell的jedis透露这种危险的做法,所以我会添加一个更“安全”的版本(为了保存事情,当有人有“-rf .pdf”文件时)
运行上面的内容后,只需打开你的收藏夹中的/tmp/dummy.sh文件即可 . 编辑并检查每一行的危险文件名,如果找到则将其评论出来 .
然后复制工作目录中的dummy.sh脚本并运行它 .
所有这些都是出于安全考虑
如果您尝试一次删除大量文件(我今天删除了目录为485,000),您可能会遇到此错误:
问题是,当您键入
rm -rf *
之类的内容时,*
将替换为每个匹配文件的列表,例如“rm -rf file1 file2 file3 file4”等等 . 有一个相对较小的内存缓冲区分配给存储这个参数列表,如果它被填满,shell将不会执行该程序 .为了解决这个问题,很多人会使用find命令查找每个文件并将它们逐个传递给“rm”命令,如下所示:
我的问题是我需要删除500,000个文件,这需要花费太长时间 .
我偶然发现了一种更快的删除文件的方式 - “find”命令内置了一个“-delete”标志!这是我最终使用的内容:
使用这种方法,我以大约2000个文件/秒的速度删除文件 - 更快!
您还可以在删除文件名时显示这些文件名:
...甚至显示将删除多少文件,然后计算删除它们所需的时间:
你可以使用bash数组:
这样,它将逐步擦除1000个文件 .
您可以使用这个赞扬
如果它们是带空格或特殊字符的文件名,请使用:
这句话用扩展名pdf(-name'* .pdf')搜索当前目录(-maxdepth 1)中的所有文件,然后删除每一个文件(-exec rm“{}”) .
表达式{}替换文件的名称,“{}”将文件名设置为字符串,包括空格或特殊字符 .
find . -type f -name '*xxx' -print -delete
在将表单源目录复制到目标时,我遇到了同样的问题
源目录有文件~3 lakcs
我使用了 cp with option -r ,这对我有用
cp -r abc/ def/
它会将所有文件从abc复制到def,而不会过长地发出参数列表的警告
我碰到了几次这个问题 . 许多解决方案将为需要删除的每个文件运行
rm
命令 . 这是非常低效的:我最后编写了一个python脚本,根据文件名中的前4个字符删除文件:
这对我很有用 . 我能够在大约15分钟内清除文件夹中超过200万个临时文件 . 我从一点点代码中评论了tar,所以任何具有最小到没有python知识的人都可以操作这段代码 .
还有一个:
printf
是一个内置的shell,据我所知,它一直是这样的 . 现在假设printf
不是shell命令(但是内置命令),它不会受到“argument list too long ...
”致命错误的影响 .因此我们可以安全地将它与shell globbing模式(如
*.[Pp][Dd][Ff]
)一起使用,然后我们将其输出通过xargs
移除(rm
)命令,这样可以确保它在命令行中符合足够的文件名,以免rm
命令失败,这是一个shell命令 .printf
中的\0
用作文件名的空分隔符,然后由xargs
命令处理,使用它(-0
)作为分隔符,因此当文件名中有空格或其他特殊字符时rm
不会失败 .我很惊讶这里没有
ulimit
答案 . 每当我遇到这个问题时,我最终都会here或here . 我知道这个解决方案有局限性但是ulimit -s 65536
似乎经常为我做这个伎俩 .我只知道解决这个问题的方法 . 我们的想法是将您拥有的pdf文件列表导出到文件中 . 然后将该文件拆分为几个部分 . 然后删除每个部分中列出的pdf文件 .
wc -l计算list.txt包含的行数 . 当你知道它有多长时,你就可以决定将它分成两半,四分之一 . 使用split -l命令例如,将它们分成600行 .
这将创建一个名为xaa,xab,xac等文件,具体取决于你如何拆分它 . 现在将这些文件中的每个列表“导入”命令rm,使用:
对不起,我的英语不好 .
试试这个如果你想删除30/90天以上()或者30/90( - )天以下的文件/文件夹,那么你可以使用下面的ex命令
例如:在90天文件/文件夹删除后90天排除上述,这意味着91,92 .... 100天
例如:对于您想要删除的最新30天文件,请使用以下命令( - )
如果你想要文件超过2天giz文件
如果你只想看过去一个月的文件/文件夹 . 例如:
超过30天以上只列出文件/文件夹Ex:
您可以创建临时文件夹,将要保留的所有文件和子文件夹移动到临时文件夹,然后删除旧文件夹并将临时文件夹重命名为旧文件夹,尝试此示例,直到您有信心实时执行:
rm -r big_folder
将删除big_folder
中的所有文件,无论多少 . 你只需要非常小心你首先要保留你想保留的所有文件/文件夹,在这种情况下它是file1.pdf
删除目录中的所有
*.pdf
/path/to/dir_with_pdf_files/
使用通配符通过
rsync
删除特定文件可能是最快的解决方案,如果您正在获取 .(可选步骤):DRY RUN . 检查将删除的内容而不删除 . `
. . .
单击rsync tips and tricks以获取更多rsync黑客
我发现对于非常大的文件列表(> 1e6),这些答案太慢了 . 这是在python中使用并行处理的解决方案 . 我知道,我知道,这不是linux ......但这里没有其他工作 .
(这节省了我几个小时)
当应用程序创建了数百万个无用的日志文件时,我遇到了类似的问题,这些文件填满了所有的inode . 我使用“locate”,将所有文件“定位”到一个文本文件中,然后逐个删除它们 . 花了一段时间,但做了这个工作!
假设输入输入目录名称并输出输出目录名称 . 然后你可以使用简单的循环来复制所有
我遇到了同样的问题,一个文件夹充满了日复一日的临时图像,这个命令帮助我清除了文件夹
与其他命令的区别在于mtime参数,该参数仅包含超过X天的文件(在示例中为50天)
多次使用,减少每天执行的日期范围,我能够删除所有不必要的文件
如果你有 grep 的类似问题,最简单的解决方案是踩一个目录并进行递归搜索 .
而不是
您可以使用:
请注意,它也会递归搜索“search_in_this_dir”目录的子文件夹 .
删除前100个文件:
rm -rf'ls |头-100'
比使用xargs更安全的版本,也不是递归的:
ls -p | grep -v '/$' | grep '\.pdf$' | while read file; do rm "$file"; done
在这里过滤我们的目录有点不必要,因为'rm'无论如何都不会删除它,并且为了简单起见它可以删除,但为什么运行肯定会返回错误的东西?
使用GNU parallel(
sudo apt install parallel
)非常简单它运行多线程命令,其中'{}'是传递的参数
例如 .
ls /tmp/myfiles* | parallel 'rm {}'
以下选项对于此问题似乎很简单 . 我从其他一些帖子得到了这个信息,但它帮助了我 .
只需运行上面的一个命令即可完成任务 .