3

请注意,我在 AWK 中需要这个答案。

如何从某个 awk 变量中删除所有小写字符?我尝试调用 gsub:

gsub(/[a-z]+/,"",varName);

不幸的是,这删除了整个字符串,好像 awk 无法区分大小写。是否有一些我不知道的正则表达式可以使用?

编辑:确认,awk 看不到小写和大写字符之间的区别。

示例 1(将在此处使用字母 f 以便更好地理解结果):

varName="CHRFProtocol";
gsub(/[a-z]/,"f",varName);

结果:ffffffffffff

示例 2(再次,将在此处使用字母 f 以便更好地理解结果):

varName="CHRFProtocol";
gsub(/[A-Z]/,"f",varName);

结果:ffffffffffff

这是合法的吗?在做什么?

4

4 回答 4

5

Your locale settings are getting in the way. Try this:

LC_ALL=C awk 'BEGIN { 
varName="CHRFProtocol";
gsub(/[a-z]/,"f",varName);
print(varName); }'

GNU awk honors locale settings, and in most national locales on Linux, regular expressions are case-insensitive. Resetting the locale to C (=POSIX) for the duration of the awk command restores case-sensitivity.

于 2013-08-07T21:22:10.360 回答
3

您应该只使用 POSIX 字符类 [[:lower:]],而不是 [az]:

gsub(/[[:lower:]]/,"",varName)

后者取决于语言环境,前者不是。

似乎在何时使用 POSIX 字符类与何时/如何设置语言环境方面存在一些混淆:

1) 当存在您感兴趣的字符集时,始终使用 POSIX 字符类(例如 [:digit:]、[:lower:]、[:punct:] 等)

2) 否则,设置 LC_ALL=C 如果你对它如何影响你的其他设置(例如逗号与句点作为千位分隔符)没问题

3) 否则,设置 LC_COLLATE=C。

有关字符类和语言环境变量的更多信息,请参见http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.htmlhttp://pubs.opengroup.org/onlinepubs/009695399/utilities/awk.html

于 2013-08-08T00:32:07.450 回答
1

示例说明了一切:

kent$  awk 'BEGIN{var="AaBbCcDDDdddEEEeee";print "before:"var;gsub(/[a-z]/,"",var);print "after:"var}' 
before:AaBbCcDDDdddEEEeee
after:ABCDDDEEE
于 2013-08-07T21:20:46.120 回答
1

要删除 awk 中的所有小写字符,请使用:

gsub(/[a-z]+/, "", varName);

您实际上是用文字字符串替换 1 次或多次出现的小写字母"f"

编辑在你纠正你的问题后:

请注意,如果您varName只包含小写字母或已经为空,那么您将在varName.

于 2013-08-07T21:00:14.670 回答