3

我正在创建一个 cron 来清理指定文件夹的子目录(仅限第一个子目录),但最近的两个文件除外,但遇到了问题。

这些是我的尝试:

find ./ -type d -exec rm -f $(ls -1t ./ | tail -n +4);
find . -maxdepth 2 -type f -printf '%T@ %p\0' | sort -r -z -n | awk 'BEGIN { RS="\0"; ORS="\0"; FS="" } NR > 5 { sub("^[0-9]*(.[0-9]*)? ", ""); print }' | xargs -0 rm -f

我还尝试创建一个文件数组,目的是使总数减去 2,但该数组并未填充所有文件:

while read -rd ''; do      x+=("${REPLY#* }");  done < <(find . -maxdepth 2 -printf '%T@ %p\0' | sort -r -z -n )

有人可以帮我解释一下他们是怎么做的吗?

4

3 回答 3

12

这列出了除了最近的两个文件之外的所有文件:

find -type f -printf '%T@ %P\n' | sort -n | cut -d' ' -f2- | head -n -2 

解释:

  • -type f仅列出文件
  • -printf '%C@ %P\n'
    • %T@显示自 1970 年以来文件的最后修改时间(以秒为单位)。
    • %P 显示文件名
  • | sort -n进行数字排序
  • | cut -d' ' -f2-删除秒表单输出,只留下文件名
  • | head -n -2显示除最后两行之外的所有内容

因此,要删除所有这些文件,只需通过xargs rm或附加管道xargs rm -f

find -type f -printf '%T@ %P\n' | sort -n | cut -d' ' -f2- | head -n -2 | xargs rm
于 2013-04-24T13:26:30.777 回答
4

与现有答案不同,这个 NUL 分隔了 find 的输出,因此对于具有绝对任何合法字符的文件名是安全的——一组包含换行符:

delete_all_but_last() {
  local count=$1
  local dir=${2:-.}
  [[ $dir = -* ]] && dir=./$dir
  while IFS='' read -r -d '' entry; do
    if ((--count < 0)); then
      filename=${entry#*$'\t'}
      rm -- "$filename"
    fi
  done < <(find "$dir" \
             -mindepth 1 \
             -maxdepth 1 \
             -type f \
             -printf '%T@\t%P\0' \
           | sort -rnz)
}

# example uses:
delete_all_but_last 5
delete_all_but_last 10 /tmp

请注意,它需要 GNU 查找和 GNU 排序。(现有的答案也需要 GNU find)。

于 2013-11-12T19:59:17.103 回答
-1

我刚刚遇到了同样的问题,这就是我解决它的方法:

#!/bin/bash

# you need to give full path to directory in which you have subdirectories
dir=`find ~/zzz/ -mindepth 1 -maxdepth 1 -type d`

for x in $dir; do
        cd $x
        ls -t |tail -n +3 | xargs rm --
done

解释:

  • 使用 tail -n +number 决定子目录中保留多少文件
于 2015-01-02T12:26:35.667 回答