查找文件并从列表总数中删除 x

Yud*_*stu 3 bash find rm

我想删除某个目录中的所有日志文件,但不是最新的 3 个。

我已经搞定了:

DATA_PATH=$(gadmin config get System.DataRoot)
ZK_PATH=${DATA_PATH}/zk/version-2

log_count=$(ls -ltrh ${ZK_PATH} | grep log | wc -l)
limit_files=`expr $log_count - 3`

echo There is ${log_count} files found in ${ZK_PATH}, ${limit_files} will be deleted, here the list:
ls -ltrh ${ZK_PATH} | grep log | head -${limit_files}

while true; do
    read -p "Are you sure to delete these files? " yn
    case $yn in
        [Yy1]* ) echo execute to delete the files; break;;
        [Nn0]* ) exit;;
        * ) echo "Please answer y or n.";;
    esac
done
Run Code Online (Sandbox Code Playgroud)

如何删除列出的 12 个文件中的 9 个?

我考虑过首先将列表打印到文件中,然后使用循环将其一一删除,但我确信有代码可以仅用一行来完成此操作。

我尝试使用find ... -delete-exec、 和xargs rm,但无法正确使用它。

我该怎么做?

Sté*_*las 6

使用 zsh 而不是 bash,可以更轻松可靠地完成此类操作:

\n
#! /bin/zsh -\ndata_path=$(gadmin config get System.DataRoot) || exit\nzk_path=$data_path/zk/version-2\nkeep=3\n\nfiles=( $zk_path/*log*(N.om) )\n\nif (( $#files > keep )); then\n  printf >&2 '%s\\n' "$#files files found in $zk_path, $(( $#files - keep )) will be deleted, here is the list from newest to oldest:"\n  shift keep files\n  printf >&2 ' - "%s"\\n' $files:t\n\n  read -q '?OK to delete? ' && rm -f -- $files\nfi\n
Run Code Online (Sandbox Code Playgroud)\n

特别令人感兴趣的是$zk_path/*log*(N.om) glob*log*它扩展到与 中的模式匹配的所有文件名$zk_path,括号(\xe2\x80\xa6)指定如果没有找到文件,则没有错误(Nullglob),我们只查找纯文件而不是目录、符号链接、devices\xe2\x80 \xa6 ( .),并且我们希望将文件按o年龄升序排序(基于m修改时间,就像ls -t这样做)。

\n


JJo*_*oao 6

在类似的情况下,我使用了以下方法(可能这不是最强大的解决方案,但在常见情况下它仍然可能有用......)

LOGDIR=my/logs    ## 

ls -dpt -- "$LOGDIR"/log* | # get log files sorted by date
  grep -v '/$'            | # but remove directories/ from the list
  tail -n +4              | # remove also the newest 3
  vidir -
Run Code Online (Sandbox Code Playgroud)

在 中vidir,如果您同意,请删除所有行(例如:使用dGvim 命令),然后离开,它们就会被删除。

vidirfrommoreutils是目录的投影编辑器(查看、重命名、删除目录内容的最佳工具)