我想删除某个目录中的所有日志文件,但不是最新的 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
,但无法正确使用它。
我该怎么做?
使用 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)
指定如果没有找到文件,则没有错误(N
ullglob),我们只查找纯文件而不是目录、符号链接、devices\xe2\x80 \xa6 ( .
),并且我们希望将文件按o
年龄升序排序(基于m
修改时间,就像ls -t
这样做)。
在类似的情况下,我使用了以下方法(可能这不是最强大的解决方案,但在常见情况下它仍然可能有用......)
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
,如果您同意,请删除所有行(例如:使用dG
vim 命令),然后离开,它们就会被删除。
vidir
frommoreutils
是目录的投影编辑器(查看、重命名、删除目录内容的最佳工具)