如何得到某一目录下所有某类文件的总大小

时间:2023-01-23 19:31:10
现在需要写一个shell脚本,需要得到某一目录下所有log*.xml文件的总大小,如果其超过某一设定值,则删除部分老文件。
但本人对shell脚本编程一窍不通,属于只会用ls级别的,请大侠们指点一下吧。

除了得到总大小外,如何按照时间删除文件也给指点一下吧。

10 个解决方案

#1


得到<dir>目录下所有log*.xml文件的总大小(单位是Byte)
find <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除<dir>目录下n天以前修改过的文件
find <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;

#2


引用 1 楼 li_yang98 的回复:
得到 <dir>目录下所有log*.xml文件的总大小(单位是Byte)
find  <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除 <dir>目录下n天以前修改过的文件
find  <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;
不对吧? 怎么没有du ?

#3


引用 2 楼 once_and_again 的回复:
引用 1 楼 li_yang98 的回复:
得到  <dir>目录下所有log*.xml文件的总大小(单位是Byte)
find   <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除  <dir>目录下n天以前修改过的文件
find   <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;

不对吧? 怎么没有du ?


-printf "%s" 已经打印出文件大小
当然du log*.xml | awk '{sum += $1}; END {print sum}'也可以得到当前目录下所有log*.xml文件的总大小(注意此时的单位是KB),但是我不太清楚如果目录下有子目录,子目录下再有log*.xml文件的话用du怎么实现,用find则没有这个问题

#4


非常感谢,得到总大小已经搞定了。
我的应用里给定的文件夹里不再关心是否存在子文件夹,所以我该成du了:
du -bs log*.xml | awk '{sum += $1}; END {print sum}'

但另外一个删除的操作,我没有描述清楚,并不是要删除几天前的文件。而是保留最近的20个文件。
在该目录下会不停的生成log_xxx.xml文件,每10M分出来一个新的,序号顺序向下排。
而且刚刚想到另外一个问题,用户可能会更改系统时间,真正最近的20个文件不一定是时间上最近的,而应该是序号最大的。
那么这样的话,要保留序号最大的20个log_xxx.xml文件而删除其他的,这个该如何处理呢?

拜托li_yang98再给指点一下吧,谢谢!

#5


谈不上指点,我也是shell新手,互相学习吧

假设你的文件名可以按字母顺序排序,保留20个序号最大的文件可以
ls -r log*.xml | sed -n '21,$p' | xargs rm -f

#6


不行啊,对于log_2.xml和log_10.xml,这样的操作会将log_10.xml删掉留下log_2.xml了,而实际应该保留log_10.xml。

#7


那可以这样
ls log*.xml | sort -rg -t"_" -k2 | sed -n '21,$p' | xargs rm -f

不过这种方法对文件名做了很多假设,必须是第一个"_"后面紧跟一个数字的形式

#8


非常感谢,基本搞定了,再多测试几种情况看看。

授人以鱼不如授人以渔啊,不如向我讲解一下ls log*.xml | sort -rg -t"_" -k2 | sed -n '21,$p' | xargs rm -f的意思,sort -rg -t,sed -n 这些参数还有xargs 都是什么含义啊?

#9


ls log*.xml就不说了
sort -rg -t"_" -k2把ls的输出结果以"_"作为分隔符分成两列(-t"_")并把第二列(-k2)按照数字从大到小排序(-rg),输出排序后的文件名
sed -n '21,$p'输出排序后的文件名的21行到最后一行
xargs rm -f把从21行到最后一行的文件名作为rm -f的参数执行删除

每个命令都有很多种用法(尤其是sed),具体的还是man吧

#10


OK,非常感谢!

#1


得到<dir>目录下所有log*.xml文件的总大小(单位是Byte)
find <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除<dir>目录下n天以前修改过的文件
find <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;

#2


引用 1 楼 li_yang98 的回复:
得到 <dir>目录下所有log*.xml文件的总大小(单位是Byte)
find  <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除 <dir>目录下n天以前修改过的文件
find  <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;
不对吧? 怎么没有du ?

#3


引用 2 楼 once_and_again 的回复:
引用 1 楼 li_yang98 的回复:
得到  <dir>目录下所有log*.xml文件的总大小(单位是Byte)
find   <dir> -type f -name "log*.xml" -printf "%s\t%p\n" | awk '{sum += $1}; END {print sum}'

删除  <dir>目录下n天以前修改过的文件
find   <dir> -type f -name "log*.xml" -mtime +n -exec rm -f {} \;

不对吧? 怎么没有du ?


-printf "%s" 已经打印出文件大小
当然du log*.xml | awk '{sum += $1}; END {print sum}'也可以得到当前目录下所有log*.xml文件的总大小(注意此时的单位是KB),但是我不太清楚如果目录下有子目录,子目录下再有log*.xml文件的话用du怎么实现,用find则没有这个问题

#4


非常感谢,得到总大小已经搞定了。
我的应用里给定的文件夹里不再关心是否存在子文件夹,所以我该成du了:
du -bs log*.xml | awk '{sum += $1}; END {print sum}'

但另外一个删除的操作,我没有描述清楚,并不是要删除几天前的文件。而是保留最近的20个文件。
在该目录下会不停的生成log_xxx.xml文件,每10M分出来一个新的,序号顺序向下排。
而且刚刚想到另外一个问题,用户可能会更改系统时间,真正最近的20个文件不一定是时间上最近的,而应该是序号最大的。
那么这样的话,要保留序号最大的20个log_xxx.xml文件而删除其他的,这个该如何处理呢?

拜托li_yang98再给指点一下吧,谢谢!

#5


谈不上指点,我也是shell新手,互相学习吧

假设你的文件名可以按字母顺序排序,保留20个序号最大的文件可以
ls -r log*.xml | sed -n '21,$p' | xargs rm -f

#6


不行啊,对于log_2.xml和log_10.xml,这样的操作会将log_10.xml删掉留下log_2.xml了,而实际应该保留log_10.xml。

#7


那可以这样
ls log*.xml | sort -rg -t"_" -k2 | sed -n '21,$p' | xargs rm -f

不过这种方法对文件名做了很多假设,必须是第一个"_"后面紧跟一个数字的形式

#8


非常感谢,基本搞定了,再多测试几种情况看看。

授人以鱼不如授人以渔啊,不如向我讲解一下ls log*.xml | sort -rg -t"_" -k2 | sed -n '21,$p' | xargs rm -f的意思,sort -rg -t,sed -n 这些参数还有xargs 都是什么含义啊?

#9


ls log*.xml就不说了
sort -rg -t"_" -k2把ls的输出结果以"_"作为分隔符分成两列(-t"_")并把第二列(-k2)按照数字从大到小排序(-rg),输出排序后的文件名
sed -n '21,$p'输出排序后的文件名的21行到最后一行
xargs rm -f把从21行到最后一行的文件名作为rm -f的参数执行删除

每个命令都有很多种用法(尤其是sed),具体的还是man吧

#10


OK,非常感谢!