我是个新手,请耐心等待。
目的是更改字符串的大小写,以使每个单词的首字母大写,其余字母小写。 (为使示例简单,此处将“单词”严格定义为字母字符;所有其他字符均视为分隔符。)
我使用以下awk命令从该网站上的另一篇文章中学习了一种使每个单词的首字母大写的好方法:echo 'abce efgh ijkl mnop' | awk '{for (i=1;i <= NF;i++) {sub(".",substr(toupper($i),1,1),$i)} print}'
-> Abcd Efgh Ijkl Mnop
通过在awk命令之前加上tr命令,可以轻松地使其余字母变为小写:echo 'aBcD EfGh ijkl MNOP' | tr [A-Z] [a-z] | awk '{for (i=1;i <= NF;i++) {sub(".",substr(toupper($i),1,1),$i)} print}'
-> Abcd Efgh Ijkl Mnop
但是,为了更多地了解awk,我想使用类似的awk构造将除第一个字母以外的所有字母的大小写更改为小写。我使用正则表达式\B[A-Za-z]+
匹配单词中除第一个单词以外的所有字母,并使用awk命令substr(tolower($i),2)
以小写形式提供这些相同的字母,如下所示:echo 'ABCD EFGH IJKL MNOP' | awk '{for (i=1;i <= NF;i++) {sub("\B[A-Za-z]+",substr(tolower($i),2),$i)} print}'
-> Abcd EFGH IJKL MNOP
请注意,第一个单词已正确转换,但其余单词保持不变。我非常感谢您解释为什么其余的单词不能正确转换以及如何使它们转换。
最佳答案
问题在于\B
(零宽度非单词边界)似乎仅在行的开头匹配,因此$1
可以工作,但$2
和后续字段与正则表达式不匹配,因此它们不会被替换并保持大写。不知道为什么\B
除了第一个字段外都不匹配... B应该匹配任何单词内的任何地方:
echo 'ABCD EFGH IJKL MNOP' | awk '{for (i=1; i<=NF; ++i) { print match($i, /\B/); }}'
2 # \B matches ABCD at 2nd character as expected
0 # no match for EFGH
0 # no match for IJKL
0 # no match for MNOP
无论如何要获得结果(仅大写该行的第一个字符),您都可以对
$0
(整行)进行操作,而不是使用for
循环:echo 'ABCD EFGH IJKL MNOP' | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2)) }'
或者,如果您仍然想将每个单词分别大写但仅使用
awk
:awk '{for (i=1; i<=NF; ++i) { $i=toupper(substr($i,1,1)) tolower(substr($i,2)); } print }'
关于regex - 用awk更改字符串的大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14139672/