Shell脚本以递归方式删除特定的图像文件

时间:2013-02-01 10:57:18

标签: bash shell ubuntu

我有一个第三方程序,它将文件上传到网络服务器。这些文件是图像,位于不同的文件夹中,名称不同。这些文件被引用到数据库中。该程序导入新图像并将其上载到这些文件夹。如果存在现有文件,则只需获取名称并添加特殊计数器,在数据库中创建新引用,并删除旧引用。但它不是删除文件,而是保留副本。

可以说,我们有一个图像文件名“109101.jpg”。 该文件有一个新版本,将以文件名“109101_1.jpg”上传。这进一步到“109101_103.jpg”为例。 现在,在此之前的所有103个文件都已过时,可以删除。

由于该程序不可编辑和第三方,我无法改变该行为。相反,我需要一个Shell脚本,它遍历这些文件夹并删除最新图像之前的所有图像。因此,只有“109101_103.jpg”才能存活,并且此号码前的所有其他人将被删除。 作为副作用,还有图像,带有双重下划线的名称(只有这些,没有三个左右)。 例如:“109013_35_1.jpg”是原始的,下一个是“109013_35_1_1.jpg”,现在是“109013_35_1_24.jpg”。所以只有“109013_35_1_24.jpg”必须存活下来。

现在我甚至没有想法,如何解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是一条单线管道,因为我觉得这样。插入换行符显示,因为我不是邪恶的。

for F in $(find . -iname '*.jpg' -exec basename {} .jpg \;
             | sed -r -e 's/^([^_]+|[^_]+_[^_]+_[^_]+)_[0-9]+$/\1/'
             | sort -u); do
    find -regex ".*${F}_[0-9]*.jpg" 
       | sort -t _ -k 2 -n | sort -n -t _ -k 4 -s | head -n -1;
done

答案 1 :(得分:0)

以下脚本删除给定目录中的文件:

#! /bin/bash
cd $1
shopt -s extglob                                       # Turn on extended patterns.
shopt -s nullglob                                      # Non matched pattern expands to null.
delete=()
for file in               +([^_])_+([0-9]).jpg \
        +([^_])_+([0-9])_+([0-9])_+([0-9]).jpg ; do    # Only loop over non original files.
    [[ $file ]] || continue                            # No files in the directory.
    base=${file%_*}                                    # Delete everything after the last _.
    num=${file##*_}                                    # Delete everything before the last _.
    num=${num%.jpg}                                    # Delete the extension.
    [[ -f $base.jpg ]] && rm $base.jpg                 # Delete the original file.
    [[ -f "$base"_$((num+1)).jpg ]] && delete+=($file) # The file itself is scheduled for deletion.
done
(( ${#delete[@]} )) && rm "${delete[@]}"

编号的文件不会立即删除,因为这可能会删除另一个文件的“跟随”文件。它们只是在数组中被记住并在最后被删除。

要递归应用脚本,您可以运行

find /top/directory -type d -exec script.sh {} \;