特定の種類の最大ファイルを除くすべてのファイルを削除する

特定の種類の最大ファイルを除くすべてのファイルを削除する

各フォルダに1つの画像のみを割り当てるように、My Music Collectionのアルバムカバーを整理しようとしています。

私のディレクトリ構造は現在次のとおりです。

/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 -f3つのglob修飾子引数を使用します。oLサイズで並べ替えます。[1,-2]2番目から最後まで一致するものだけを保持します(PATTERN([-1])最後の一致、2PATTERN([-2])番目から最後の一致、PATTERN([1,-2])最初から2番目から最後まで(最初と2番目から最後を含む)。;Nパターンが拡張されていない、またはパターンファイルと一致しない場合は、エラーを報告するのではなく空のリストを生成します。

残りのファイルが呼び出された場合、またはディレクトリにファイルがないと、cover.jpg無害なエラーが発生する可能性があります。.jpgこれを防ぐには、mv呼び出しを次に変更します。

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

これは最初に名前を変更してから削除する代わりに使用できます。一致するが一致しないファイルを選択するオプションがPATTERN1~PATTERN2必要な構文を使用します。配列に要素が1つ以上含まれているかどうかをテストします。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/

関連情報