如何删除最旧的n组具有相同前缀的文件?

问题描述 投票:1回答:1

在Linux中,我使用InfluxDB,它可以为存档目的备份数据库。每个备份包含一系列具有相同前缀“ / tank / Backups / var / Influxdb / 20191225T235655Z”的文件。和不同的扩展名。

我想编写一个bash脚本,该脚本首先删除最旧的现有备份,然后创建一个新的备份(这里我仅粘贴删除的备份:]

ls -tp /tank/Backups/var/Influxdb/* | grep -v '/$' | sed -E 's/\..+//' | \
  sort -ru | sed 's/$/.*/' | tail -n +4 | xargs -d '\n' -r rm --

但是,当我以“ sudo”运行脚本时,会得到

rm: cannot remove '/tank/Backups/var/Influxdb/20191225T235655Z.*': No such file or directory

当运行引用的脚本时,除最新部分外,我得到:

/tank/Backups/var/Influxdb/20190930T215357Z.*
/tank/Backups/var/Influxdb/20190930T215352Z.*

是正确的。另外,如果我手动写

sudo /tank/Backups/var/Influxdb/20190930T215357Z.*

命令成功。

为什么脚本报告错误?

我正在使用Ubuntu 18.04,文件夹“ / tank”是ZFS卷。

linux bash xargs
1个回答
0
投票

最好做:

find /tank/Backups/var/Influxdb/* -mtime +5 -delete

删除5天之前的文件。

然后,您可以运行下一个命令


0
投票

解释错误

此答案仅是为了解释该错误并更深入地了解正在发生的事情。如果您只是在寻找一种优雅的解决方案,请搜索其他答案。

当运行引用的脚本时,除最新部分外,我得到:

/tank/Backups/var/Influxdb/20190930T215357Z.*
/tank/Backups/var/Influxdb/20190930T215352Z.*

是正确的

列出的字符串不是您想要的。当您将这些路径传递到rm时,它们会像原义字符串一样看到它们,即,两个文件名以原义*结尾的文件。由于您没有此类文件,因此会出现错误。

当您在控制台中手动输入rm *时,bash(不是rm!)会globbingbash搜索文件,并用找到的文件列表替换*。仅在此之后,bash才会执行rm foundFile1 foundFile2 ...rm从未看到*

bash不会处理管道中的字符串,但rm会处理管道中的命令。 rm不起作用。

您可以在管道中运行bash,并使其扩展先前插入的*。为此,将管道中的最后一个命令替换为xargs -r bash -c 'rm -- $*' --。但是,请注意,此处未引用您的路径。如果文件名中有空格或文字*,该命令将中断。对于引用来说,这是必需的,因为引号"*"不会被bash扩展。

要引用文件,必须在bash命令中插入* glob:

ls -tp /tank/Backups/var/Influxdb/* | grep -v '/$' | sed -E 's/\..+//' |
sort -ru | tail -n +4 | xargs -d\\n -L1 -r bash -c 'rm -- "$0."*'

以上命令只是您命令的简单修复。它既不优雅也不坚固。强烈建议使用find之类的工具。

© www.soinside.com 2019 - 2024. All rights reserved.