我正在编写一个 Bash 脚本来清理我的音乐。
我想让它格式化所有文件名并制作它们,所以通过一点互联网搜索我写了这一行:
sed -i -e 's/[-_]/ /g' -e 's/ \+/ /g' -e **'s/\<[a-z]/\U&/g'** -e "s/$artist //g" -e "s/$album //g"
我曾经将文件名添加到文本文件,然后将其 sed,但后来我不知道如何将新名称应用于文件。
然后我开始尝试重命名并设法获得完全相同的结果 除了粗体部分,它应该使单词中的每个首字母大写。
rename 's/[-_]/ /g' * && rename 's/\s+/ /g' * && **rename 's/\s\w{1}/*A-Z*/g' *** && rename 's/^\d+[[:punct:]]\s//g' * && rename "s/$artist\s//g" * && rename "s/$album\s//g" * && rename "s/($ext)//g" *
现在,重命名中的代码可以正常工作(至少令人满意),在空格字符后只找到一个字母,但替换是有问题的。在这种情况下,我尝试了多种不同的方法,结果都是焦点的第一个字母准确地交换为 A-Z。
在重命名手册页中,它说要将小写字母变为大写字母,您可以执行“s/a-z/A-Z/g”,但很容易看出它仅在找到 a-z A-Z 时才适用。 所以这就是我需要帮助的地方。
如果有人知道如何像在 sed 示例中那样做,那将是一个奖励,其中\< 匹配每个单词的开头,因为目前,我的重命名命令不会应用于第一个单词,也不会如果出于显而易见的原因有多个看起来像“光盘名称 [Disc 1]”的光盘,它是否适用。
最佳答案
这是一个 Perl 问题,因为 rename
是用 Perl 编写的,并且关于如何执行重命名的说明是一个 Perl 命令。
在 s///
中,为了让替换知道要插入哪个字母的大写版本,它必须从输入中“捕获”字母。模式中的括号执行此操作,将捕获的字母存储在变量 $1
中。并且 \u
在替换中使下一个字符大写。
所以你可以这样做:
$ rename 's/\s(\w)/ \u$1/g' *
请注意,替换部分必须在大写字母前插入一个空格,因为模式中包含一个空格,所以空格和原始字母都会被替换。您可以使用 \b
来避免这种情况,这是一个仅在单词边界匹配的零宽度断言:
$ rename 's/\b(\w)/\u$1/g' *
此外,您也不需要 {1}
,因为 \w
(与正则表达式中的其他符号一样)默认匹配单个字符。
最后,rename(1)中的例子其实是y/A-Z/a-z/
,使用了y///
操作符,不是 s///
。 y///
是一个完全不同的运算符,它将所有出现的一组字母替换为另一组字母;在这里对您没有用,您只需要将一些字符设为大写即可。
关于regex - Linux重命名命令首字母大写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14241691/