我有如下文件。我想保留 9 月 30 日、10 月 30 日......的文件并删除其余的。
-rw-r--r-- 1 nbswmcm advboprd 13463761 Sep 2 01:19 vtm_data_12month_20140902.txt
-rw-r--r-- 1 nbswmcm advboprd 13474125 Sep 3 01:51 vtm_data_12month_20140903.txt
-rw-r--r-- 1 nbswmcm advboprd 13492755 Sep 4 01:57 vtm_data_12month_20140904.txt
-rw-r--r-- 1 nbswmcm advboprd 13499981 Sep 5 01:59 vtm_data_12month_20140905.txt
-rw-r--r-- 1 nbswmcm advboprd 13507296 Sep 7 08:39 vtm_data_12month_20140907.txt
-rw-r--r-- 1 nbswmcm advboprd 13508099 Sep 9 04:02 vtm_data_12month_20140909.txt
-rw-r--r-- 1 nbswmcm advboprd 13508886 Sep 10 01:33 vtm_data_12month_20140910.txt
-rw-r--r-- 1 nbswmcm advboprd 13513056 Sep 11 02:25 vtm_data_12month_20140911.txt
-rw-r--r-- 1 nbswmcm advboprd 13512334 Sep 12 02:36 vtm_data_12month_20140912.txt
-rw-r--r-- 1 nbswmcm advboprd 13512391 Sep 14 08:41 vtm_data_12month_20140914.txt
-rw-r--r-- 1 nbswmcm advboprd 13515984 Sep 16 02:35 vtm_data_12month_20140916.txt
-rw-r--r-- 1 nbswmcm advboprd 13516946 Sep 17 02:27 vtm_data_12month_20140917.txt
-rw-r--r-- 1 nbswmcm advboprd 13523528 Sep 18 02:39 vtm_data_12month_20140918.txt
-rw-r--r-- 1 nbswmcm advboprd 13520200 Sep 19 02:28 vtm_data_12month_20140919.txt
-rw-r--r-- 1 nbswmcm advboprd 13514677 Sep 21 09:33 vtm_data_12month_20140921.txt
-rw-r--r-- 1 nbswmcm advboprd 13518239 Sep 23 02:29 vtm_data_12month_20140923.txt
-rw-r--r-- 1 nbswmcm advboprd 13488002 Sep 24 02:51 vtm_data_12month_20140924.txt
-rw-r--r-- 1 nbswmcm advboprd 13491370 Sep 25 02:38 vtm_data_12month_20140925.txt
-rw-r--r-- 1 nbswmcm advboprd 13414606 Sep 26 02:42 vtm_data_12month_20140926.txt
-rw-r--r-- 1 nbswmcm advboprd 13411621 Sep 28 08:59 vtm_data_12month_20140928.txt
-rw-r--r-- 1 nbswmcm advboprd 13529594 Sep 30 02:52 vtm_data_12month_20140930.txt
-rw-r--r-- 1 nbswmcm advboprd 13520560 Oct 1 02:54 vtm_data_12month_20141001.txt
-rw-r--r-- 1 nbswmcm advboprd 13519613 Oct 2 02:54 vtm_data_12month_20141002.txt
-rw-r--r-- 1 nbswmcm advboprd 13534704 Oct 3 02:19 vtm_data_12month_20141003.txt
-rw-r--r-- 1 nbswmcm advboprd 13545015 Oct 5 08:47 vtm_data_12month_20141005.txt
-rw-r--r-- 1 nbswmcm advboprd 13541506 Oct 7 02:51 vtm_data_12month_20141007.txt
-rw-r--r-- 1 nbswmcm advboprd 13556650 Oct 8 02:31 vtm_data_12month_20141008.txt
-rw-r--r-- 1 nbswmcm advboprd 13551903 Oct 9 02:33 vtm_data_12month_20141009.txt
-rw-r--r-- 1 nbswmcm advboprd 13567484 Oct 10 02:33 vtm_data_12month_20141010.txt
-rw-r--r-- 1 nbswmcm advboprd 13569503 Oct 12 08:40 vtm_data_12month_20141012.txt
-rw-r--r-- 1 nbswmcm advboprd 13567657 Oct 14 02:25 vtm_data_12month_20141014.txt
-rw-r--r-- 1 nbswmcm advboprd 13574132 Oct 15 02:40 vtm_data_12month_20141015.txt
-rw-r--r-- 1 nbswmcm advboprd 13581260 Oct 16 02:50 vtm_data_12month_20141016.txt
-rw-r--r-- 1 nbswmcm advboprd 13585758 Oct 17 02:27 vtm_data_12month_20141017.txt
-rw-r--r-- 1 nbswmcm advboprd 13587851 Oct 19 10:02 vtm_data_12month_20141019.txt
-rw-r--r-- 1 nbswmcm advboprd 13591515 Oct 21 02:43 vtm_data_12month_20141021.txt
-rw-r--r-- 1 nbswmcm advboprd 13602271 Oct 22 02:59 vtm_data_12month_20141022.txt
-rw-r--r-- 1 nbswmcm advboprd 13604358 Oct 23 03:22 vtm_data_12month_20141023.txt
-rw-r--r-- 1 nbswmcm advboprd 13607622 Oct 24 02:52 vtm_data_12month_20141024.txt
-rw-r--r-- 1 nbswmcm advboprd 13605666 Oct 26 10:25 vtm_data_12month_20141026.txt
-rw-r--r-- 1 nbswmcm advboprd 13612303 Oct 28 02:32 vtm_data_12month_20141028.txt
-rw-r--r-- 1 nbswmcm advboprd 13617526 Oct 29 02:49 vtm_data_12month_20141029.txt
-rw-r--r-- 1 nbswmcm advboprd 13627963 Oct 30 02:38 vtm_data_12month_20141030.txt
答案1
在 GNU 系统上,使用特定的文件名模式,
ls -r | uniq -w23
会给你保留的。所以你可以把它们移走:
ls -r | uniq -w23 | xargs mv -t ../to-keep/
并删除所有剩余文件。
23 是 的长度vtm_data_12month_201409
。因此,uniq
将仅返回具有相同 23 个字符长前缀的文件列表中的第一个文件(在反向排序的文件列表中)。
一次性完成:
ls -r | awk -F_ 'a[substr($NF,1,6)]++'
其中列出了要删除的文件。
ls -r | awk -F_ 'a[substr($NF,1,6)]++' | xargs rm -f
(假设文件名不包含空白、引号或反斜杠字符)。
在这里,我们不是查看前 23 个字符,而是查看最后一个_
字符之后的前 6 个字符。
答案2
使用logrotate
命令。这是处理/var/log
.它可以根据日期或大小轮换日志。
看看/etc/cron.daily/logrotate
和/etc/logrotate.conf
。您应该能够放入一个条目/etc/logrotate.conf
来处理您想要旋转的文件。
另请参阅此网站:http://www.rackspace.com/knowledge_center/article/understanding-logrotate-utility
如果您需要更多帮助,请告诉我。我会尽力。
好的,所以我的系统/etc/cron.daily/logrotate
每天都会调用 logrotate 一次。 /etc/logrotate.conf
告诉我们logrotate
如何处理每个文件。所以你只需要担心修改/etc/logrotate.conf
您只需将这样的条目添加到您的/etc/logrotate.conf
文件中即可。
/var/log/LOGFILENAME {
monthly
create 0664 root root
rotate 1
}
然后重新启动您的系统或 cron 或您所做的更改生效。您还可以通过logrotate
直接调用来测试您的配置文件,因此:
/usr/sbin/logrotate /etc/logrotate.conf
该行rotate 1
告诉logrotate
您保留一份旧副本,这样您最终将获得两个月的日志:上个月和本月。如果您只想保留当前月份的日志,请更改rotate 1
为。rotate 0
答案3
您需要普遍解决这个问题还是只解决一次?如果您只需要解决一次,有时简单的解决方案是最好的。我们可以在 Bash 中使用大括号扩展:
rm vtm_data_12month_2014{09,10}{01..29}.txt
这可能适用于您的情况,因为:
- 我们要发送的参数数量
rm
不太可能超过 ARG_MAX,并且 - 十月和九月您想要停留的日期是相同的。
如果您需要更普遍地解决此问题,则需要考虑不同月份在不同日期结束的事实(例如,10 月于 31 日结束,但您的示例仅包含截至 30 日的数据)。
如果可以依赖示例中的文件命名方案,则以下命令将删除每月可用的除最新文件之外的所有文件(基于文件名,而不是与文件创建或修改相关的实际时间戳):
get_years() {
find ./ -type f | cut -d'_' -f4 | cut -c1-4 | sort | uniq
}
get_months_for_year() {
year=$1
find ./ -iname "vtm_data_12month_${year}*.txt" -type f | cut -d'_' -f4 | cut -c5-6 | sort | uniq
}
get_latest_for_year_month() {
year=$1
month=$2
find ./ -iname "vtm_data_12month_${year}${month}*.txt" -type f | cut -d'_' -f4 | cut -c7-8 | sort | tail -1
}
for year in $(get_years); do
for month in $(get_months_for_year $year); do
latest=$(get_latest_for_year_month $year $month)
end=$(($latest - 1))
for i in $(seq 1 $end); do
day=$(printf '%02d' $i)
rm vtm_data_12month_${year}${month}${day}.txt
done
done
done
除 bash 之外,具有 DateTime 库的语言可能会为您提供更简洁、更可靠的解决方案。如果某些天的文件丢失,此处提供的两种解决方案都会发出错误。
答案4
使用 bash 脚本检查日期的有效性并生成日期范围很困难且容易出错。最好的选择是使用python
或perl
或任何其他可以进行深入检查的高级脚本语言。我已经更新了脚本,以便它可以删除日期范围内的文件并排除日期范围。
选项将类似于
删除范围内的文件
./dfile.py --from 20140929 --to 20141001 --range
删除范围之外的文件
./dfile.py --from 20140929 --to 20141001 --out-range
如果参数给出错误,该程序还会生成有用的帮助消息。
#!/usr/bin/env python3
import os
import sys
import argparse
import datetime
parser = argparse.ArgumentParser()
parser.add_argument('--from', dest="fromd", type=str, required=True, help="From date")
parser.add_argument('--to', dest="tod", type=str, required=True, help="To date")
parser.add_argument('--range', dest='drange', action='store_true', help="Delete files between the given date")
parser.add_argument('--out-range', dest="orange", action='store_true', help="Delete files apart form the given date")
args = parser.parse_args()
if args.drange and args.orange:
print('Enter either --range or --out-range option')
sys.exit(1)
elif not (args.drange or args.orange):
print('You must select either --range or --out-range option')
sys.exit(1)
from_date = args.fromd
to_date = args.tod
path='/tmp/tmp.54JUy4ZP6x/'
try:
from_date = datetime.datetime.strptime(from_date, '%Y%m%d').date()
to_date = datetime.datetime.strptime(to_date, '%Y%m%d').date()
except ValueError:
print('Check if the date has been given in YYYYMMDD format')
sys.exit(1)
files = [ x for x in os.listdir(path) if x.endswith('.txt') ]
for file in files:
file_date = datetime.datetime.strptime(file[17:25], '%Y%m%d').date()
if args.orange:
# Delete files out of date range
if not from_date < file_date < to_date:
print('Deleting file {}'.format(file))
os.remove(path + '/' + file)
else:
# Delete files within date range
if from_date < file_date < to_date:
print('Deleting file {}'.format(file))
os.remove(path + '/' + file)
这里所有参数都是可配置的,除了path
需要在程序中更改的参数之外。
希望对您有帮助。