AWK中的忽略大小写

31
以下命令按预期工作。
# some command | awk '/(\<^create\>|\<^alter\>|\<^drop\>)/,/;/' 
create table todel1 (id int) max_rows=2
/*!*/;
alter table todel1 engine=InnoDB
/*!*/;
create database common
/*!*/;
create database rules
/*!*/;

但它只匹配小写的"create"、"alter"等。我想在awk语句中使用IGNORECASE开关,这样它就会返回所有搜索项的实例。


2
被接受的答案中的示例错误地将IGNORECASE = 1评估为条件(带有副作用),而不是块中的语句。这个条件是真实的,并且将导致每一行至少被打印一次。 - mwfearnley
4个回答

25

在您的awk命令开头添加IGNORECASE = 1;,如下所示:

bash-3.2$ echo "Create" | awk '/^create/;'
bash-3.2$ echo "Create" | awk 'IGNORECASE = 1;/^create/;'
Create

21
由于它不需要针对每行输入执行,所以请将其放在“BEGIN”块或命令行中进行设置。 - Dennis Williamson
5
请注意,这是 gawk 的特性。至于 Dennis 提到的第二点,他的意思是类似于: awk '/一堆正则表达式/' IGNORECASE=1 - SiegeX
2
在awk版本20070501中,这不起作用。echo "No match" | awk 'IGNORECASE = 1;/^create/;'会返回No match。如果除了正则表达式之外还有其他内容,它似乎不会添加隐式if语句。 - ceyko
4
@ceykooo说这对我也不起作用。 但是这个对我有效: echo "No match" | awk 'tolower($0) ~ /^create/' - Daniel Pérez Rada
3
将其置于BEGIN块或任何其他块中,否则它将无法正常工作。当它不在<code>{ }</code>块中时,在gawk 3.1.6和4.1.1以及可能的所有版本中,所有文本行都将匹配。例如,<code>echo -e "a\nb\nc" | awk 'IGNORECASE = 1; /B/' - </code> 输出四行包含a、b、b、c的结果!<code>echo -e "a\nb\nc" | awk 'BEGIN { IGNORECASE = 1 } /B/' - </code> 只输出包含b的一行。 - kbulgrien
显示剩余6条评论

20
下面这行代码执行的是 OR 测试而不是 AND 测试:
echo -e "Create\nAny text" | awk 'IGNORECASE = 1;/^create/;'
Create
Create
Any text

BEGIN这个特殊单词解决了问题:

echo -e "Create\nAny text" | awk 'BEGIN{IGNORECASE = 1}/^create/;'
Create

希望这能有所帮助。

Sebastien。


4
这不完全是一个OR测试,它只是评估两个表达式(其中一个始终评估为真),因此每个输入行将被打印一次或两次。 - mwfearnley

12

对于那些使用旧版本的awk并且IGNORECASE标志无效的人:

选项1

echo "CreAte" | awk '/^[Cc][Rr][Ee][Aa][Tt][Ee]/'

选项2(感谢@mwfearnley)

echo "CreAte" | awk 'tolower($0) ~ /^create/'

1
那些使用旧版 awk 的人...比如 Mac 用户 :( - Joel Mellon
晚回复了,但是尝试安装GNU版本:http://brewformulas.org/Gawk @JoelMellon - Juan Diego Godoy Robles
2
只是想说,https://www.gnu.org/software/gawk/manual/html_node/Case_002dsensitivity.html 建议在非GNU awk中使用 tolower($0) ~ /.../ - mwfearnley
1
谢谢 @mwfearnley 我会尝试并反馈结果。 - Juan Diego Godoy Robles

11
这有点晚了,但是这个问题的两个 答案(包括被接受的答案)都提到了使用awk 'IGNORECASE=1;...'——即将IGNORECASE=1作为一个条件而不是块语句。
这样做是不正确的。它确实设置了变量,但它也(无意中)将其作为布尔表达式进行评估,返回true。
没有块的true条件将导致该行始终被打印。如果它恰好匹配以下模式,它也将被打印第二次。
被接受的答案可能意味着awk '{IGNORECASE=1} ...',它在每行文本上设置IGNORECASE变量。这可以通过使用BEGIN条件仅分配一次来进一步改进。但更清洁的解决方案是使用-v标志在脚本逻辑之外设置参数:
awk -v IGNORECASE=1 '/(\<^create\>|\<^alter\>|\<^drop\>)/, /;/'

请注意,IGNORECASE 是特定于gawk的。为了使用非gawk特定的方法,GNU Awk用户指南建议在模式匹配中使用tolower
awk '(tolower($0) ~ /(\<^create\>|\<^alter\>|\<^drop\>)/), /;/'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接