bash Linux 重命名命令大写首字母

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14241691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:12:39  来源:igfitidea点击:

Linux Rename command uppercase first letter

regexlinuxbashsedrename

提问by Jompa

I'm writing a Bash script for cleaning up in my music.

我正在编写一个 Bash 脚本来清理我的音乐。

I wanted it to format all the file names and making them and so with a little internet search I wrote this line:

我希望它格式化所有文件名并制作它们,所以通过一点互联网搜索我写了这一行:

sed -i -e 's/[-_]/ /g' -e 's/ \+/ /g' -e **'s/\<[a-z]/\U&/g'** -e "s/$artist //g" -e "s/$album //g"

Which I used to add the file names to a text file and then sed it, but then I didn't know how to apply the new names to the files.

我曾经将文件名添加到文本文件中,然后将其 sed,但后来我不知道如何将新名称应用于文件。

So then I started experimenting with rename and managed to get the exact same result except for the bolded parts, which is supposed to make every first letter in a word uppercase.

然后我开始尝试重命名并设法获得完全相同的结果,除了粗体部分,它应该使单词中的每个第一个字母大写。

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" *

Now, the code in rename is working (satisfactorily at least), finding only one letter after a SPACE character, but it's the replacement that is problematic. I've tried numerous different approaches, all leaving me with the result that the first letter in focus get exchanged to exactly A-Z in this case.

现在,重命名中的代码正在工作(至少令人满意),在空格字符后只找到一个字母,但有问题的是替换。我尝试了许多不同的方法,结果都是在这种情况下焦点中的第一个字母被交换为 AZ。

In the rename manual page it says to make lower case uppercase you do 's/a-z/A-Z/g' but it's easy to figure that it only applies when it finds a-z A-Z. So this is what I need help with.

在重命名手册页中,它说要使小写大写,您可以使用“s/az/AZ/g”,但很容易看出它仅在找到 az AZ 时才适用。所以这就是我需要帮助的。

A bonus would be if someone knows how to do it like in the sed example, where the \< matches the beginning of each word, because at the moment, my rename command won't apply to the very first word and neither will it apply if there are multiple discs looking like "Disc name [Disc 1]" for obvious reasons.

如果有人知道如何像在 sed 示例中那样做,其中 \< 匹配每个单词的开头,这是一个奖励,因为目前,我的重命名命令不适用于第一个单词,也不会适用如果出于显而易见的原因有多个光盘看起来像“光盘名称 [光盘 1]”。

回答by Smylers

This is sort-of a Perl question, since renameis written in Perl, and instructions for how to perform the renaming are a Perl command.

这是一个 Perl 问题,因为它rename是用 Perl 编写的,关于如何执行重命名的说明是一个 Perl 命令。

In a s///in order for the substitution to know which letter to insert the upper-case version of, it has to ‘capture' the letter from the input. Parentheses in the pattern do this, storing the captured letter in the variable $1. And \uin a substitution makes the next character upper-case.

在 as///中,为了让替换知道要插入大写版本的哪个字母,它必须从输入中“捕获”该字母。模式中的括号执行此操作,将捕获的字母存储在变量中$1。并\u在替换中使下一个字符大写。

So you can do:

所以你可以这样做:

$ rename 's/\s(\w)/ \u/g' *

Note that the replacement part has to insert a space before the upper-case letter, because the pattern includes a space and so both the space and the original letter are being replaced. You can avoid this by using \b, a zero-width assertion which only matches at a word boundary:

请注意,替换部分必须在大写字母之前插入一个空格,因为该模式包含一个空格,因此空格和原始字母都将被替换。您可以通过使用\b仅在单词边界匹配的零宽度断言来避免这种情况:

$ rename 's/\b(\w)/\u/g' *

Also you don't need the {1}in there, because \w(like other symbols in regexs) matches a single character by default.

此外,您也不需要{1}在那里,因为\w(与正则表达式中的其他符号一样)默认匹配单个字符。

Finally, the example in rename(1)is actually y/A-Z/a-z/, using the y///operator, not s///. y///is a completely different operator, which replaces all occurrences of one set of letters with another; that isn't of use to you here, where it's only some characters you want making upper-case.

最后,rename(1) 中的示例实际上是y/A-Z/a-z/使用y///运算符,而不是s///y///是一个完全不同的运算符,它将一组字母的所有出现替换为另一组字母;这对您在这里没有用,其中只有一些您想要大写的字符。

回答by Perleone

rename -nv 's{ (\A|\s) (\w+) }{\u}xmsg'

This looks for the beginning of the string \Aor for whitespace \sfollowed by at least one or more word characters (a-z, 0-9, underscore) \w+. It will uppercase the first character of all word sequences.

这会查找字符串的开头\A\s后跟至少一个或多个单词字符 (az, 0-9, underscore) 的空格\w+。它将大写所有单词序列的第一个字符。