查找文件并按文件名参数删除

时间:2017-03-22 16:57:55

标签: bash duplicates

我有一个包含大量图片的文件夹。在此文件夹中包含包含高分辨率图像的子文件夹。图像可以是.png,.jpg或.gif。 一些图像是重复的,称为 a.jpg a.hi.jpg abcgif abchi.gif 。文件名总是不同的,永远不会是a.gif,a.jpg或a.png。我想我不需要照顾延期。 这些是具有不同分辨率的相同图像。

现在我想编写一个脚本来删除所有低分辨率图像。但是有些文件不像b.png那样具有高分辨率。所以我只想在有高分辨率图像的情况下删除。

我想我必须做这样的事情,但无法弄清楚到底是怎么回事。

find . -type f -name "*" if {FILENAME%hi*} =2 --delete smallest else keep file  

有人可以帮忙吗?感谢

3 个答案:

答案 0 :(得分:2)

以下内容可以完成这项工作:

#!/bin/bash
while IFS= read -r -d '' hi
do
    d=$(dirname "$hi")
    b=$(basename "$hi")
    low="${b//.hi./}"
    [[ -e "$d/$low" ]] && echo rm -- "$d/$low"  #dry run - if satisfied, remove the echo
done < <(find /some/path -type f -name \*.hi.\* -print0)

它如何运作:

  • 查找名称中包含.hi.的所有文件。 (不仅是图片,您可以扩展find更具限制性的
  • 找到所有找到的图片
    • 获取目录,他在哪里
    • 并获取文件名(无目录)
    • 名称中的
    • ,删除字符串.hi.的所有出现(也称为“低级”名称
    • 检查是否存在低位图像
    • 如果存在则删除。

答案 1 :(得分:1)

您可以使用bash extended glob功能,您可以先启用

shopt -s extglob

并使用模式

!(pattern-list)
Matches anything except one of the given patterns.

现在存储不包含字符串hi

的文件
shopt -s extglob
fileList=()

fileList+=( !(*hi*).jpg )
fileList+=( !(*hi*).gif )
fileList+=( !(*hi*).png )

您可以打印一次数组,看它是否列出了您需要的所有文件

printf "%s\n" "${fileList[@]}"

并删除这些文件

for eachfile in "${fileList[@]}"; do
    rm -v -- "$eachfile"
done

(或)正如Benjamin.W在下面的评论中所建议的那样做

rm -v -- "@{fileList[@]}"

答案 2 :(得分:-1)

  

现在我想写一个脚本来删除所有低分辨率图像

此脚本可用于:

find /path/to/dir -type f -iname '*.hi.png' -or -iname '*.hi.gif' -or -iname '*.hi.jpg' | while read F; do LOWRES="$(echo "$F" | rev | cut -c7- | rev)$(echo "$F" | rev | cut -c 1-3 | rev)"; if [ -f "$LOWRES" ]; then echo rm -fv -- "$LOWRES"; fi; done

您可以运行它以查看将首先删除哪些文件。如果您对搜索结果不满意,请在echo命令之前删除rm

这是非单行版本,但是脚本:

#!/bin/sh

find /path/to/dir -type f -iname '*.hi.png' -or -iname '*.hi.gif' -or -iname '*.hi.jpg' |
    while read F; do
        NAME="$(echo "$F" | rev | cut -c7- | rev)"
        EXTENSION="$(echo "$F" | rev | cut -c 1-3 | rev)"
        LOWRES="$NAME$EXTENSION"
        if [ -f "$LOWRES" ]; then
            echo rm -fv -- "$LOWRES"
        fi
    done