我有一个第三方程序,它将文件上传到网络服务器。这些文件是图像,位于不同的文件夹中,名称不同。这些文件被引用到数据库中。该程序导入新图像并将其上载到这些文件夹。如果存在现有文件,则只需获取名称并添加特殊计数器,在数据库中创建新引用,并删除旧引用。但它不是删除文件,而是保留副本。
可以说,我们有一个图像文件名“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”必须存活下来。
现在我甚至没有想法,如何解决这个问题。有什么想法吗?
答案 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 {} \;