我有图像,我需要删除一些相同大小的文件。但不需要删除所有此类图像,而只需删除队列中的下一个图像(按字母顺序排列):
1.png # 23,5 Kb
2.png # 24,6 Kb
4.png # 24,6 Kb > remove
8.png # 24,6 Kb > remove
16.png # 23,5 Kb
答案1
如果您使用的是 Linux 或以其他方式可以访问 GNU 工具,您可以执行以下操作:
last=-1; find . -type f -name '*.png' -printf '%f\0' | sort -nz |
while read -d '' i; do
s=$(stat -c '%s' "$i");
[[ $s = $last ]] && rm "$i";
last=$s;
done
解释
last=-1
:将变量设置$last
为-1
。find . -type f -name '*.png' -printf '%f\0'
:查找当前目录中名称以 结尾的所有文件.png
,并打印其名称后跟空字符。sort -gz
:按数字 ( )对\0
分隔的输入 ( ) 进行排序。这会产生一个排序的文件名列表。-z
-n
while read -d '' i; do
:读取文件名列表。设置正确处理 NULL 分隔数据所需的-d ''
字段分隔符。\0
s=$(stat -c '%s' "$i");
:变量$s
现在保存当前文件的大小 ($i
)。[[ $s = $last ]] && rm "$i";
:如果当前文件的大小与上一个文件的大小相同,则删除该文件。last=$s
:设置$last
为当前文件的大小。现在,如果下一个文件具有相同的大小,则上一步将删除它。
答案2
POSIX的实现ls
支持一个-S
选项来提供按大小排序的列表(并且看起来是按相同大小的名称排序)。您可以将列表通过管道传输到 shell 循环中,记住前一项的大小并删除“重复项”。
这样做的缺点是获取文件名(如果您碰巧喜欢在文件名中使用空格)。
或者,如果您使用具有实用程序的平台之一(例如 Linux 或 BSD)stat
,您可以使用它来制作仅包含大小和文件名的固定格式列表,然后进行排序那,将其传送到一个检查重复大小的 simple(r) 脚本。
这个问题的一个复杂之处是该示例没有使用 shell-order 来表示“alphabetic”,因为16.png
遵循8.png
. -g
GNU 和 BSDsort
实用程序句柄的选项那(但它不在POSIX)。
鉴于 的这些问题sort
,您的脚本可能应该获取排序名称的列表(按照您的首选顺序)并用于stat
连续获取每个文件的大小。
这是一个使用 GNU 进行说明的简单示例(将“rm”更改为“echo”)stat
:
#!/bin/sh
last=x
# the sed command strips a leading "./", which confuses "sort -g"
find . -name '*.png' |sed -e 's,^./,,' | sort -g | while true
do
read item
[ -z "$item" ] && break
size=$(stat -c '%s' "$item")
echo "$size>$item"
if [ "x$size" = "x$last" ]
then
echo "rm -f \"$item\""
fi
last="$size"
done