특정 유형의 가장 큰 파일을 제외한 모든 파일 삭제

특정 유형의 가장 큰 파일을 제외한 모든 파일 삭제

각 폴더에 하나의 이미지만 할당되도록 내 음악 컬렉션의 앨범 표지를 정리하려고 합니다.

내 디렉토리 구조는 현재 다음과 같습니다.

/path/to/music/Album Name/
/path/to/music/Album Name/1 - Track one.flac
...
/path/to/music/Album Name/cover.jpg (either this)
/path/to/music/Album Name/folder.jpg (or this)
/path/to/music/Album Name/Album Name.jpg (or this is the largest file)
/path/to/music/Album Name/AlbumArtSmall.jpg  

(또한 Windows Media Player에서 생성된 추가 저해상도 이미지)

모든 폴더를 스캔하고 가장 큰 jpg를 제외한 모든 폴더를 삭제하고 이름을 cover.jpg.

레이블에서 알 수 있듯이 cygwin이 설치되어 있지만 문제가 더 쉬워지면 bash 및 zsh에 액세스할 수 있는 Ubuntu로 부팅할 수도 있습니다.

답변1

zsh(Cygwin 또는 Linux에서 사용할 수 있음)에서는 다음을 사용할 수 있습니다.글로벌 예선가장 큰 파일을 선택하세요. 이는 이미지 크기가 아닌 바이트 크기 기준으로 가장 큰 파일입니다. 이는 고해상도 이미지를 우선시하므로 아마도 맞을 것입니다.

for d in /path/to/music/**/*(/); do
  rm -f $d/*.jpg(oL[1,-2]N)
  mv $d/*.jpg $d/cover.jpg
done

루프는 모든 하위 디렉터리를 재귀적으로 순회합니다 /path/to/music. 접미사는 (/)디렉토리와 일치하는 것을 제한합니다. rm -f세 개의 glob 한정자 인수를 사용합니다. oL크기별로 정렬합니다. [1,-2]두 번째에서 마지막까지 일치하는 항목만 유지합니다( PATTERN([-1])마지막 일치, PATTERN([-2])두 번째에서 마지막 일치, PATTERN([1,-2])첫 번째부터 두 번째부터 마지막까지(첫 번째 및 두 번째부터 마지막 ​​포함). N; 패턴이 확장되지 않거나 패턴이 파일과 일치하지 않는 경우 오류를 보고하는 대신 빈 목록을 생성합니다 .

나머지 파일이 호출되었거나 디렉터리에 파일이 없으면 cover.jpg무해한 오류가 발생할 수 있습니다 . .jpg이를 방지하려면 mv호출을 다음으로 변경하십시오.

[[ -e $d/cover.jpg ]] || mv $d/*.jpg $d/cover.jpg

이는 먼저 이름을 바꾼 다음 삭제하는 대신 사용할 수 있습니다. 일치 하지만 일치하지 않는 파일을 선택하는 옵션이 PATTERN1~PATTERN2필요한 구문을 사용합니다 . 배열에 요소가 하나 이상 포함되어 있는지 테스트합니다 .extended_globPATTERN1PATTERN2((#jpgs))jpgs

setopt extended_glob
for d in /path/to/music/**/*(/); do
  jpgs=($d/*.jpg(oL))
  ((#jpgs)) || continue
  [[ $jpgs[1] == */cover.jpg ]] || mv $jpgs[1] $d/cover.jpg
  rm -f $jpgs[2,-1]
done

답변2

이것은슈워츠 변환당신을 위한:

stat -c "%s %n" *.jpg | sort -n | cut -d " " -f 2- | head -n -1 |
while IFS= read -r filename; do echo rm "$filename"; done

stat크기와 파일 이름을 출력하고, 크기 필드를 정렬 및 제거하고, 가장 큰 필드를 무시하고, 결과 파일을 반복하는 데 사용됩니다 .

답변3

GNU 찾기를 사용하세요.

#!/usr/bin/env bash
# GNU find + bash4 / ksh93v / zsh
# Get the largest file matching pattern in the given directories recursively
${ZSH_VERSION+false} || emulate ksh
${BASH_VERSION+shopt -s lastpipe extglob}

function getLargest {
    typeset -A cur top || return
    typeset dir x
    for dir in "$2"/*/; do
        [[ -d $dir ]] || return 0
        getLargest "$1" "${dir%/}" || return
        top[size]=-1
        find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | {
            while :; do
                for x in cur\[{size,name}\]; do
                    IFS= read -rd '' "$x" || break 2
                done
                if (( cur[size] > top[size] )); then
                    top[size]=${cur[size]} top[name]=${cur[name]}
                fi
            done
            mv -- "${dir}"{"${top[name]}",cover.jpg}
            rm -f -- "${dir}"!(cover.jpg)
        }
    done
}

# main pattern dir [ dir ... ]
function main {
if [[ -n $1 ]]; then
    typeset dir pattern=$1
    shift
    for dir; do
        [[ -d $dir ]] || return
            getLargest "$pattern" "$dir"
        done
    else
        return 1
    fi
}

main \*.jpg /path/to/music/

관련 정보