如何使用 find 命令从文件名中删除 (1)

如何使用 find 命令从文件名中删除 (1)

我最近在 Mac OS 10.7 (Lion) 上使用 XLD 将所有 FLAC 文件转换为较低的采样率 44.1 kHz 和位深度 24 位(因为 iPhone/iPod 不支持高于此值的任何内容)。

虽然我告诉 XLD 覆盖以前的所有文件,但 XLD(1)在每个文件的末尾附加了一个,例如来自

some_song.m4a

some_song(1).m4a

所以现在我想(1)从我转换的所有 FLAC 文件中删除它。

我知道我可能可以使用一些程序甚至 AppleScript 来重命名文件,但我想学习使用老式的命令行方式。

我知道这find . -name *\(1\).m4a将获取所有转换后的 FLAC 文件。

接下来我知道我必须对所有找到的文件进行一些处理-exec并重命名。mv但我不知道如何保留原始文件名并仅删除(1).

也许我需要进行一些组正则表达式捕获来存储我不想修改的文件名部分?或者也许不可能在一行中完成所有操作,我应该创建一个 shell 脚本(我不太习惯这样做,但我愿意尝试一下)。

欢迎任何提示或建议!谢谢!

答案1

不要尝试解析find除非万不得已,否则输出。重要的是要认识到,在 Unix 文件系统上,文件名不是字符串(常见的误解),而是二进制斑点它可以包含除/和 空字符之外的任何字符。安全、正确地解析文件名已经够痛苦的了,99% 的情况下你只想完全避免这样做(看看这个有多么毛茸茸的)sed下面的表达式有多毛茸茸的)@yarek 的回答是,甚至这并不能涵盖所有情况)。值得庆幸的是,在这种情况下有一个更简单的方法:

find . -name '*(1).m4a' -execdir sh -c \
'for arg; do mv "$arg" "${arg%(1).m4a}".m4a; done' _ {} \+

答案2

在 Debian 和 Ubuntu 上,我可以用来rename 's/\(1\)//' *.m4a解决你的问题。

答案3

在 zsh 中,使用兹马夫:

autoload zmv      # you can put this line in your .zshrc
zmv '(*)\(1\)(*)' '$1$2'

在第二个参数(新名称)中,$1引用源模式中$2带括号的组。(PATTERN)编写此重命名的另一种方法是

zmv '(*)' '${1/\(1\)/}'

答案4

这是一个执行此操作的小脚本:

for var in `find . -type f -name "*(1).m4a"`; do
    new=`echo $var | cut -d'(' -f1`;
    mv $var $new.m4a;
done

相关内容