bash 脚本用于对文本文件中的重复项进行排序

bash 脚本用于对文本文件中的重复项进行排序

我将音乐库中的所有 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 {}' \;

相关内容