Mac OSX Bash中实现标题大小写转换,避免变音符号后字母大写
解决带变音符号文本的标题大小写转换问题
问题场景
在Mac OSX Bash(英国英语区域设置,未设置LC_*环境变量)环境下,存在test.txt文件,内容如下:
Ève
Eve
eve
执行以下命令尝试将内容转为标题大小写:
cat test.txt | gsed 's/.*/\L&/; s/[a-z]*/\u&/g'
得到的结果不符合预期:
ÈVe
Eve
Eve
问题在于第一个姓名应为Ève,但变音符号后的字母v被错误大写。
问题原因
原命令的第二个替换规则s/[a-z]*/\u&/g存在两个问题:
- 在当前区域设置下,
[a-z]仅匹配ASCII小写字母,不包含带变音符号的Unicode字母(如è)。 - 全局替换(
g修饰符)会将每一段连续的[a-z]序列的首字母大写,导致转全小写后的ève中,v和e被分别识别为独立序列,最终v被大写为V。
解决方案
调整替换逻辑,仅将每行的第一个Unicode字母大写,其余字符保持小写。可以使用以下两种命令:
方案1:分两步处理
cat test.txt | gsed 's/.*/\L&/; s/\p{L}/\u&/'
- 第一步
s/.*/\L&/:将整行文本转为全小写。 - 第二步
s/\p{L}/\u&/:仅匹配并大写行内第一个Unicode字母(\p{L}匹配所有类型的Unicode字母),无全局修饰符,因此只处理一次。
方案2:单步捕获替换
cat test.txt | gsed 's/^\(\p{L}\)\(.*\)/\u\1\L\2/'
- 捕获行首的第一个Unicode字母(
\p{L}),将其大写(\u\1)。 - 捕获剩余所有字符,将其转为小写(
\L\2)。
两种方案执行后都会得到正确结果:
Ève
Eve
Eve
内容的提问来源于stack exchange,提问作者Richard L
相关产品推荐
相关产品推荐

