1

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

可以说,我们有一个图像文件名“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”必须生存。

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

4

2 回答 2

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
于 2013-02-01T16:12:40.577 回答
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 {} \;
于 2013-02-01T11:24:05.373 回答