【问题标题】:Keep only one version of each file (bash)每个文件只保留一个版本 (bash)
【发布时间】:2012-09-11 16:12:06
【问题描述】:

我想删除文件夹中的多余文件。类似的东西

cat_1.jpg
cat_2.jpg
cat_3.jpg
dog_10.jpg
dog_100.jpg

减少到

cat_3.jpg
dog_100.jpg

即只取每个文件的版本号后缀最高的,其余的删除。

这很像

list the files with minimum sequence

但是那里的 bash 答案有一个“for ... in ...”。我有数千个文件名。

编辑:

文件名约定错误。可能还有其他下划线(例如 cat_and_dog_100.jpg)。我需要它只取最后一个下划线之后的数字。

【问题讨论】:

  • 我会使用 Perl 脚本,避开 bash。可以改用 Python 或 Ruby。需要注意确保删除 fish_90.jpg 并保留 fish_103.jpg
  • 以后,请考虑使用适当的版本控制软件,而不是编号的文件名。
  • 文件名是否可预测,即总是<name>_<numbers>.jpg
  • 这些文件名不是我制作的。他们来自制作网站的副本。是的,它们是可预测的:名称和数字之间只有一个下划线,其他任何地方都没有。

标签: bash


【解决方案1】:

假设您的文件名始终采用<name>_<numbers>.jpg 的形式,这里有一个快速破解:

while read filename; do
    prefix=${filename/%_*/}  # Get text before underscore
    if [ "$prev_prefix" != "$prefix" ]; then  # we see a new prefix
        echo "Keeping filename"
        prev_prefix=$prefix
    else  # same prefix
        echo "Deleting $filename"
        rm $filename
    fi
done < <(find . -maxdepth 1 -name "*.jpg"| sort -n -t'_' -k1,2)

这是如何工作的:

  1. 首先按&lt;name&gt;,然后按&lt;numbers&gt; 对所有*.jpg 文件进行排序。
    • 所有具有相同前缀的文件将被分组在一起,最高的&lt;number&gt;首先出现
  2. 遍历文件名列表并删除文件,除非找到新的&lt;name&gt;(应该是&lt;number&gt; 最高的那个)

请注意,使用find 代替ls *.jpg,这样我们可以更好地处理大量文件。


免责声明:这是处理文件和版本控制的一种相当脆弱的方式,不应作为长期解决方案采用。请注意发布在该问题上的 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-23
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-21
    相关资源
    最近更新 更多