bash:删除所有超过 1 个月的文件,但保留周一的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20034415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:26:29  来源:igfitidea点击:

bash: Delete all files older than 1 month, but leave files from Mondays

bashsh

提问by freento

I have a lot of daily backup archives. To manage disk usage, I need a bash script that will delete all files older than 1 month, but keep all files created on Mondays, even if they are older than 1 month.

我有很多日常备份档案。为了管理磁盘使用情况,我需要一个 bash 脚本来删除所有超过 1 个月的文件,但保留在星期一创建的所有文件,即使它们超过 1 个月。

For example, this will delete all files last modified more than 30 days ago:

例如,这将删除 30 多天前最后修改的所有文件:

 find /path/to/files* -type f -mtime +30 -delete

But I don't really know how to keep files created on Mondays.

但我真的不知道如何保留周一创建的文件。

回答by janos

Slightly simpler and more cautious version of @JoSo's answer:

@JoSo 回答的稍微简单和谨慎的版本:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(date +%a -r "") = Mon || echo rm ""' -- {} \;

The differences:

区别:

  • Using date -rto get the last modification date of a file directly
  • Using %ato work with more comprehensible weekday names
  • Just echo the rm "$1"first to review what will be deleted. If looks good, then either stick | shat the end to really execute, or remove the echo
  • 使用date -r直接获取文件的最后修改日期
  • 使用%a工作更加理解工作日名称
  • 只需回显rm "$1"第一个即可查看将要删除的内容。如果看起来不错,那么要么坚持| sh最后真正执行,要么删除echo

However, @JoSo is right to point out that date +%ais locale dependent, so these versions would be indeed safer:

然而,@JoSo 正确地指出这date +%a是依赖于语言环境的,所以这些版本确实更安全:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(date +%u -r "") = 1 || echo rm ""' -- {} \;
find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test $(LC_TIME=C date +%a -r "") = Mon || echo rm ""' -- {} \;

回答by Jo So

As findto my knowledge has no weekday check, you need to call an external program.

find我所知没有工作日检查,你需要调用一个外部程序。

find /path/to/files -type f -mtime +30 \
    -exec sh -c \
        '[ "$(date +%u -d @"$(stat -c %Y "")")" != 1 ] && rm ""' -- {} \;

Update: Using the -rswitch to date(Kudos to Janos) and only testing, not deleting inside the shell command probably yields the cleanest possible version:

更新:使用-r切换到date(Kudos to Janos) 和只测试,而不是在 shell 命令中删除可能会产生最干净的版本:

find /path/to/files -type f -mtime +30 \
    -exec sh -c 'test "$(date +%u -r "")" != 1' -- {} \; \
    -print  # or -delete instead

回答by user2196728

you can use

您可以使用

stat -c %y yourfile

to get the date the file was created.

获取文件的创建日期。

Then extract the date with cut to have a var like myvar=yyyymmdd

然后使用 cut 提取日期以具有类似 myvar=yyyymmdd 的 var

and finally use

最后使用

date +%u --d $myvar
date +%u --d 20130822

it will return the day of week, if it returns 1 it was monday. In my case it return 4 because 22/08/2013 was a Thursday

它将返回星期几,如果返回 1 则是星期一。就我而言,它返回 4,因为 22/08/2013 是星期四

Edit : if you can get all these working as a simple command line as Jo So suggest, it's better !

编辑:如果你能像 Jo So 建议的那样将所有这些作为一个简单的命令行工作,那就更好了!

回答by brablc

What about avoiding subprocesses in loop:

如何避免循环中的子进程:

find /path/to/files -type f -mtime +30 -printf '%Ta %p\n' \
    | grep -v ^Mon | cut -c5- | tr "\n" "##代码##" | xargs -0 rm -v