我的照片库里乱七八糟。我有这样的文件:
image-1.jpg
image-1.jpeg
image-2.jpg
现在,当存在同名但扩展名为 .jpg 的文件时,我想删除所有扩展名为 .jpeg 的照片。
我怎样才能做到这一点?
答案1
for f in *.jpeg; do
[ -e "${f%.*}.jpg" ] && echo rm -- "$f"
done
(如果高兴就删除echo
)。
通过zsh
一次rm
调用:
echo rm -- *.jpeg(e'{[ -e $REPLY:r.jpg ]}')
(更改*
为**/*
以递归方式执行此操作,D
如果您还想考虑隐藏文件或隐藏目录中的文件,请添加 glob 限定符)。
答案2
改编自类似问题的答案:
find . -type f -name '*.jpeg' -exec sh -c '
for pathname do
jpg_pathname=${pathname%.jpeg}.jpg
if [ -f "$jpg_pathname" ]; then
printf "Would remove %s\n" "$pathname"
# rm "$pathname"
fi
done' sh {} +
.jpeg
这将查找当前目录中或当前目录下具有文件名后缀的所有文件的路径名。对于尽可能大批量的这些路径名,将调用一个简短的内联脚本。该脚本循环遍历当前批次的路径名,并检测具有相同文件名主干后跟.jpg
.如果一个.jpeg
文件有对应的.jpg
文件,则该.jpeg
文件被删除(如果注释掉的rm
被激活)。
较短的版本(删除了安全注释并且没有文本输出):
find . -type f -name '*.jpeg' -exec sh -c '
for pathname do
[ -f "${pathname%.jpeg}.jpg" ] && rm "$pathname"
done' sh {} +
(你会注意到,这结果是一个递归变体斯特凡·查泽拉斯的回答)
答案3
readonly path="${1:-./}"
for file in "${path}"*.jpeg; do
if [[ -f ${file%.jpeg}.jpg ]]; then
rm -- "$file"
printf '%s\n' "removed duplicate file ${file}"
fi
done
顶部的只读变量允许您将目录路径作为参数传递给脚本。如果没有给出 arg,则默认为当前目录。
它只是循环遍历 var 路径指定的目录中以“.jpeg”结尾的所有文件。然后它会删除扩展名并测试是否存在具有 .jpg 扩展名的相同文件。如果 .jpg 重复文件存在,则 .jpeg 文件被视为重复文件,并将其删除。
答案4
当前答案回答了问题正文中的具体情况,但针对删除的情况全部其他文件,我合并了斯特凡·查泽拉斯的回答和这个答案关于排除全局匹配:
shopt -s extglob
for f in *.jpeg; do
[ -e "$f" ] && echo rm -- "${f%.*}".!(jpeg)
done