【问题标题】:Delete all but one timestamped files删除除一个时间戳文件外的所有文件
【发布时间】:2016-12-19 12:46:15
【问题描述】:

我有一组带时间戳的文件,如下所示:

./mysql_foo_bar_hostname_table1_mysql_dump_20160927112627.dmp
./mysql_foo_bar_hostname_table2_mysql_dump_20160927121555.dmp
./mysql_foo_bar_hostname_table3_mysql_dump_20160927121703.dmp
./mysql_foo_bar_hostname_table4_mysql_dump_20160927112718.dmp
./mysql_foo_baz_hostname_table5_mysql_dump_20160919122659.dmp
./mysql_foo_bar_hostname_table6_mysql_dump_20160927110851.dmp
./mysql_foo_bar_hostname_table7_mysql_dump_20160927133419.dmp
./mysql_foo_bar_hostname_table6_mysql_dump_20160927100456.dmp
./mysql_foo_bar_hostname_table6_mysql_dump_20160927113037.dmp
./mysql_foo_bar_hostname_table6_mysql_dump_20160927102752.dmp
./mysql_foo_bar_hostname_table6_mysql_dump_20160927095924.dmp
./mysql_foo_baz_hostname_table8_mysql_dump_20160919140536.dmp
./mysql_foo_bar_hostname_table9_mysql_dump_20160927100730.dmp

我想保留具有相同“前缀”(即“_<timestamp>.dmp”之前的位(前缀是时间戳之前的所有内容)的所有文件中的最新文件。

例如,在上面的列表中,我想保留mysql_foo_bar_hostname_table6_mysql_dump_20160927113037.dmp,所有其他的都有唯一的“前缀”,所以我也想保留它们。我通常在 bash 中工作,但如果有更有效的方法,我会很高兴知道。提前感谢您的任何帮助。

【问题讨论】:

  • _.dmp 前缀不同之前,表名因文件而异?您想要每个表类型的最新信息或总体逻辑是什么?
  • 您预期的文件不是最新的,以下文件比您指出的文件旧./mysql_foo_bar_hostname_table7_mysql_dump_20160927133419.dmp ./mysql_foo_bar_hostname_table3_mysql_dump_20160927121703.dmp ./mysql_foo_bar_hostname_table2_mysql_dump_20160927121555.dmp
  • 我已经编辑了我原来的问题。 @Inian,它基本上是每张桌子最新的。 Ed Morton,我的错误格式破坏了我给出的示例。

标签: bash shell grep find


【解决方案1】:

在批量删除文件之前应该小心。所以这里首先进行试运行。切换到包含这些文件的目录 (cd $DIR) 并运行:

ls -r mysql*.dmp|awk 'a[substr($0, 1, match($0,"_[^_]*$"))]++'

这应该会生成您要删除的文件列表。 如果是这样,将上述命令的输出传送到xargs rm 以实际删除这些文件,即运行:

ls -r mysql*.dmp|awk 'a[substr($0, 1, match($0,"_[^_]*$"))]++'|xargs rm

解释

对于每个前缀,它会保留名称具有最新时间戳的文件,并删除其他文件。这里,prefix 表示到最后一个下划线 (substr($0, 1, match($0,"_[^_]*$"))) 为止的文件路径。 ls -r 输出中文件名的排序顺序将每个前缀的最新文件放在旧文件之前。 a[<prefix>]++ 确保不打印每个前缀的第一个条目。 xarg 运行 rm,文件名作为参数传入。

【讨论】:

    【解决方案2】:
    eval "$( \
      ls \
      | awk -F '_dump_|.dmp' '
         {
         if ( Dates[$1] < $2 ) Dates[$1] = $2
          else Files[$0]++
         }
         END {
           for (File in Files) if ( Files[File] == 1) print "rm " Files[ File]
           }'
      )"
    
    • 使用 awk 创建具有“不是最大”时间值文件的删除 cmd(基于名称)
    • 假设没有 空格 文件名(如您的示例中)
    • 如果文件的实时时间与名称相同,ls -t 可能有用
    • 使用非“oneliner”更明确,如果需要,oneliner 很容易制作
    • 我不鼓励这种工作,因为任何情况下都可能因文件名错误而出错,因此ls -t ./mysql_foo_bar_hostname_*.dmp安全性的最低要求

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多