【发布时间】:2015-05-20 15:35:31
【问题描述】:
我需要计算一个单词中有多少个大写字母。我该怎么做?
【问题讨论】:
-
欢迎来到 Stack Overflow!发布问题时,请确保包含您尝试过的代码、所做的研究以及展示错误行为的具体、最小示例。然后,我们可以看看它并提供帮助。
标签: linux string shell uppercase
我需要计算一个单词中有多少个大写字母。我该怎么做?
【问题讨论】:
标签: linux string shell uppercase
我会使用grep -o '[A-Z]' 匹配大写,然后计算发生了多少次:
$ grep -o '[A-Z]' <<< "heLLo" | wc -l
2
或者甚至更好(thanks mklement0,总是提供很好的信息!),使用[[:upper:]],这样大写也将考虑在您的语言环境中定义的那些:
$ grep -o '[[:upper:]]' <<< "heLLo" | wc -l
2
【讨论】:
[[:upper:]] 而不是[A-Z],这样该命令也可以处理带重音的大写字符。
我喜欢这个:
echo "$word" | tr -dc A-Z | wc -c
只需删除所有非大写字符并计算剩下的字符。
您可能更喜欢 tr -dc [:upper:],但我发现 A-Z 更易于使用。
【讨论】:
A-Z 和[:upper:] 是等价的;看我的回答。
tl;dr
对于一种区域设置感知并因此也适用于重音字符的解决方案,请使用:
任一:[[:upper:]] 的变体fedorqui's helpful grep-based answer。
echo "heLLÖ, world" | tr -dC '[:upper:]' | wc -m # -> 3
需要进行更改才能正确处理非 ASCII 多字节编码字符。
请继续阅读以获取详细说明。
使上述命令具有区域感知能力的关键:
tr 的-C 选项使用基于字符 的补码,而-c 使用基于byte 的补码;而-c 和-C 在某些tr 实现中的行为可能相同,POSIX defines only -C as the locale-aware variant。
[:upper:] 确保使用活动区域设置的 定义构成大写字符的内容,而A-Z 仅包含 unaccented(仅限 ASCII ) 从“A”到“Z”的字母。
wc 的-m 选项计数字符(在现在流行的UTF-8 编码中可能包含多个 字节);相比之下,-c 计数 bytes,在上面的示例中,它会报告 4 而不是预期的 3,因为 Ö 被编码为 2 个字节。
现在让我们看一下威廉的回答中的一句话:
您可能更喜欢
tr -dc [:upper:],但我发现A-Z更易于使用。
[:upper:] 和A-Z 可以互换使用,并且选择其中一个只是偏好或方便的问题 - 但是,如上所述,[:upper:] 是区域设置感知的,而 @ 987654345@ 不是。[:upper:] unquoted 使其受路径名扩展(通配)的影响,这意味着如果当前目录恰好包含名为:、u、@987654349 的文件@、e 或 r、[:upper:] 将扩展为它们的名称,这显然是不希望的。原因是未引用的[:upper:] 被shell 视为字符类。wc -c,计数 bytes,恰好与 A-Z 一起工作,因为根据定义,所有匹配的字母都是 单字节 字符;但切换到[:upper:] 以了解区域设置需要切换到wc -m,以便正确计算(可能是多字节)字符。【讨论】: