删除除特定类型的最大文件之外的所有文件

jCl*_*k94 4 bash zsh cygwin

我试图在我的音乐收藏中组织专辑封面,以便每个文件夹只分配一个图像。

我的目录结构目前看起来像:

/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  
Run Code Online (Sandbox Code Playgroud)

(加上 Windows 媒体播放器生成的其他低分辨率图像)

我想扫描每个文件夹并删除除最大的 jpg 之外的所有文件夹并将其重命名为cover.jpg.

正如标签所示,我已经安装了 cygwin,但也可以启动到 Ubuntu,在那里我可以访问 bash 和 zsh,如果这使问题更容易。

Gil*_*il' 5

在 zsh(您可以在 Cygwin 或 Linux 中使用)中,您可以使用glob 限定符来选择最大的文件。这是按字节大小计算的最大文件,而不是图像尺寸——这可能是正确的,因为它优先处理高分辨率图像。

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

循环/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
Run Code Online (Sandbox Code Playgroud)

这是一种先重命名然后删除的替代方法。它使用PATTERN1~PATTERN2需要extended_glob选项的语法来选择匹配PATTERN1但不匹配的文件PATTERN2((#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
Run Code Online (Sandbox Code Playgroud)