我正在写一个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" *
现在,重命名代码正在工作(至少令人满意),在SPACE字符后只找到一个字母,但它是有问题的替代品。我已经尝试了许多不同的方法,所有这些都让我得到的结果是,在这种情况下,焦点的第一个字母恰好被交换为A-Z。
在重命名手册页中,它表示制作小写字母大写,你可以做&#39; s / a-z / A-Z / g&#39;但很容易发现只有在找到a-z A-Z时它才适用。 所以这就是我需要帮助的地方。
奖励将是如果有人知道如何在sed示例中执行此操作,其中\&lt;匹配每个单词的开头,因为此刻,我的重命名命令不会适用于第一个单词,如果有多个光盘看起来像#34;光盘名称[光盘1]&#,它也不会适用34;原因很明显。
答案 0 :(得分:10)
这是一个Perl问题,因为rename
是用Perl编写的,有关如何执行重命名的说明是Perl命令。
在s///
中,为了让替换知道插入大写版本的字母,它必须“捕获”来自输入的字母。模式中的括号执行此操作,将捕获的字母存储在变量$1
中。并且\u
在替换中使下一个字符为大写。
所以你可以这样做:
$ rename 's/\s(\w)/ \u$1/g' *
请注意,替换部件必须在大写字母前插入空格,因为该图案包含空格,因此空格和原始字母都将被替换。您可以使用\b
来避免这种情况,$ rename 's/\b(\w)/\u$1/g' *
是一个零宽度断言,仅在字边界处匹配:
{1}
此外,您不需要\w
,因为y/A-Z/a-z/
(与正则表达式中的其他符号一样)默认情况下与单个字符匹配。
最后,重命名(1)中的示例实际上是y///
,使用的是s///
运算符,而不是y///
。 {{1}}是一个完全不同的运算符,它将一组字母的所有出现替换为另一组;这对你来说没什么用处,只有你想要制作大写的一些角色。
答案 1 :(得分:3)
rename -nv 's{ (\A|\s) (\w+) }{$1\u$2}xmsg'
这将查找字符串\A
的开头或空格\s
,后跟至少一个或多个单词字符(a-z,0-9,下划线)\w+
。它将大写所有单词序列的第一个字符。