我将音乐库中的所有 flac 都转换为 mp3,这样我就可以将 flac 移到外部驱动器。我在 Windows 中使用了 dbpoweramp,我确信它转换了所有文件,但当我今天早上醒来时,上网本已经重新启动了。
因此,我制作了一个包含所有音乐的列表,并使用 sort 按字母顺序排列。因此,我得到了如下内容:
~/music/a/a.flac
~/music/a/a.mp3
~/music/a/b.flac
~/music/a/b.mp3
~/music/b/a.mp3
~/music/b/b.mp3
~/music/c/a.flac
~/music/c/a.mp3
请注意,我有一个仅包含 mp3 的目录,因为我的整个库并不是 flac。
我想要的是一个 bash 脚本,它将检查所有以 .flac 结尾的行下面是否有一行相同的内容,只是以 .mp3 结尾。
我该如何实现这一点,如果你能解释一下脚本的作用,那就太酷了。
我猜显示任何以 .flac 结尾但没有匹配的 .mp3 的行是相当重要的,因为它们仍然需要转换。
答案1
awk '
root && $0 != root ".mp3" {printf("%d: %s.flac\n", line, root)}
/.flac$/ {
root=$0
sub(/.flac$/, "", root)
line = NR
next
}
{ root = "" }
' filename
它是如何工作的?
从以 开头的行开始/.flac$/
,对于以“.flac”结尾的每一行,创建一个名为的变量,root
其中包含行号减去扩展名。保存当前行号。跳转到下一行以避免擦除刚刚设置的根变量。
转到第一行。此表达式root && $0 != root ".mp3"
表示:root
非空且当前行 ( $0
) 不等于根变量的值加上“.mp3”。如果此表达式的计算结果为真,则当前行不是与前一个 FLAC 文件对应的 MP3 文件。
最后一行删除了 root 变量的值。只有当前行不是 FLAC 文件时才会到达脚本的这一部分,因此我们不想与下一行进行比较。
答案2
我找到了另一种方法,使用 diff,但尚未将其变成 bash 脚本。如果我找到方法,我会在这里发布。
格伦 (Glenn) 发布了一个非常实用的脚本,但我最终按照以下方式进行操作。
我制作了两个排序文件,一个是 .flac,一个是 .mp3,find ~/music -name *.flac | sort > ~/documents/flac
并且find ~/music -name *.mp3 | sort > ~/documents/mp3
然后我删除了 vim 中的扩展
vim ~/documents/flac
:%s/.....$//
:w
:e ~/documents/mp3
:%s/....$//
:wq
然后我做了,diff ~/documents/mp3 ~/documents/flac | grep '>'
如果一切操作正确的话,什么都不会显示,并且显示没有 mp3 的 flac 行。
我很确定我已经将其分解为一行或多行,但 Glenn 的回答对我拥有的文件非常有用。
答案3
使用 find 也是可能的。
在 find 后使用 while 循环:
find . -name '*.flac' | while read file ; do test -f `dirname $file`/`basename $file .flac`.mp3 && echo $file; done
使用(大量)子 shell:
find . -name '*.flac' -exec sh -c 'test -f `echo {} |sed s/\.flac$/.mp3/` && echo {}' \;