删除除最新文件之外的所有内容

删除除最新文件之外的所有内容

假设我有一个目录ḟoo/,其中包含大量文件,这些文件具有某种目录结构。我需要保留其中一些文件,但不是全部。

有没有办法(就地)删除除最新的 500 个之外的所有内容?

答案1

我经常做这个任务,并且使用以下变体。它是一个结合各种简单工具的管道:查找所有文件、添加文件修改时间、排序、删除文件修改时间、首先显示除第 500 行之外的所有行,然后删除它们:

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | tail -n +501 | \
    while read file; do rm -f -- "$file"; done

一些评论:

  • 如果您使用“bash”,您应该使用“read -r file”,而不仅仅是“read file”。

  • 使用“perl”删除文件更快(并且比 while 循环更好地处理文件名中的“奇怪”字符,除非您使用“read -r file”):

    ... | tail -n +501 | perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'
    
  • 有些版本的“tail”不支持“-n”选项,因此您必须使用“tail +501”。跳过前 500 行的一个可移植方法是

     ... | perl -wnle 'print if $. > 500' | ...
    
  • 如果您的文件名包含换行符,它将不起作用。

  • 它不需要 GNU 查找。

结合以上内容,您可以得到:

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | perl -wnle 'print if $. > 500' | \
    perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'

答案2

这是我在 Python 3 中执行的操作。它也应该适用于其他操作系统。测试后,请确保取消注释实际删除文件的行。

import os,os.path
from collections import defaultdict

FILES_TO_KEEP = 500
ROOT_PATH = r'/tmp/'

tree = defaultdict(list)

# create a dictionary containing file names with their date as the key
for root, dirs, files in os.walk(ROOT_PATH):
    for name in files:
        fname = os.path.join(root,name)
        fdate = os.path.getmtime( fname )
        tree[fdate].append(fname)

# sort this dictionary by date
# locate where the newer files (that you want to keep) end
count = 0
inorder = sorted(tree.keys(),reverse=True)
for key in inorder:
    count += len(tree[key])
    if count >= FILES_TO_KEEP:
        last_key = key
        break

# now you know where the newer files end, older files begin within the dict
# act accordingly
for key in inorder:
    if key < last_key:
        for f in tree[key]:
            print("remove ", f)
            # uncomment this next line to actually remove files
            #os.remove(f)
    else:
        for f in tree[key]:
            print("keep    ", f)

答案3

我不知道“500 个最新”是什么意思,但使用 find 可以删除超过 X 分钟/天的内容。文件示例,超过 2 天:

find foo/ -mtime +2 -a -type f -exec rm -fv \{\} \;

首先测试一下:

find foo/ -mtime +2 -a -type f -exec ls -al \{\} \;

注意“\;”前的反斜杠和空格。请参阅 find 手册页以了解更多信息。

答案4

我认为命令的-mtime和选项对你很有用。你可以查看更多信息。-newerfindman find

相关内容