删除除一个带时间戳的文件之外的所有文件

时间:2016-12-19 12:46:16

标签: bash shell grep find

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

./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工作,但如果有更有效的方法,我会很高兴知道它。提前感谢您的任何帮助。

2 个答案:

答案 0 :(得分: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

说明

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

答案 1 :(得分:0)

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,其中&#34;不是最大的&#34;时间价值文件(基于名称)
  • 假设没有 space 文件名(如样本中)
  • 如果文件的实时时间与名称相同,则ls -t可能有用
  • 使用not&#39; oneliner&#39;更明确的是,如果需要,oneliner很容易制作
  • 我不鼓励这种工作,因为任何情况都会因文件名错误而出错,因此ls -t ./mysql_foo_bar_hostname_*.dmp至少是安全