我该如何使这个 AWK 命令不区分大小写?

3
我将尝试使用awk命令仅打印.csv文件中字段的出现次数。例如,在名为test.csv的文件中,如下所示:
layla;rebel;TAT
han_solo;rebel;TAT
darth_vader;empire;DKS
yoda;rebel;TAT

使用以下命令:
cat test.csv | ./how_many_are_we.sh dks

我希望您能提供以下输出:

1

以下是我在how_many_are_we.sh中的代码(区分大小写可用):

#! /bin/bash
awk -F ";" -v location=$1 'BEGIN {count=0;} { if ($3 == location) count+=1} END {print count}'

我尝试在不同的位置添加IGNORECASE=1,但似乎找不到使其起作用的正确方法。

请原谅我措辞不太好,并感谢您的帮助。


1
"Ignorecase" 是 gawk 特有的,你确定你正在运行 gawk 吗? - Ed Morton
2个回答

6
你可以改变输入值和第三个字段的大小写,然后比较它们的值以确保无论如何输入都不会受到影响。
#!/bin/bash
awk -F ";" -v location="$1" 'BEGIN {location=tolower(location);count=0;} { if (tolower($3) == location) count+=1} END {print count+0}' Input_file

根据 Glenn 先生的评论,使用 shell trick 在变量本身中将其转换为小写。

#!/bin/bash
awk -v location="${1,,}" 'BEGIN{FS=";"} (tolower($3) == location){count+=1} END{print count+0}' Input_file

或者更加简洁易懂地使用awksh方式,将awk命令改为以下形式(上面是原始命令,下面是修改后的awksh命令):

awk -v location="$1" 'BEGIN{location=tolower(location);FS=";"} (tolower($3) == location){count+=1} END{print count+0}'


注意: 如果要使用 IGNORECASE=1,你可以在 BEGIN 段落中加入 BEGIN{IGNORECASE=1} 或者像一个 awk 变量一样加入 -v IGNORECASE="1"

另外,顺便提醒,原始命令的 shebang 中 #!/bin/bash 之间有空格,这是不正确的,我已经在这里修复了它。



1
谢谢您的快速回复。这很好用!我仍然想知道为什么IGNORECASE=1没有起作用,它是特定于gawk还是我只是错放了它? - Odil
1
@Odil,抱歉你更新了你的评论,现在在这里回复它,我在我的解决方案中已经提到了如何使用IGNORECASE的理想情况,请确保你只使用这种方式。 - RavinderSingh13
3
我建议使用-v location="${1,,}"将输入参数转换为小写。这样做可以避免在每一行中都要使用tolower(location)的繁琐操作。 - glenn jackman
1
@RavinderSingh13 感谢指出 shebang 错误,我之前并不知道。 - Odil

0
通常,如果您有一个可以轻松处理小写输入的脚本,您可以使用 tr 转换输入流,以便它也可以操作混合大小写输入。
$ command | tr '[:upper:]' '[:lower:]' | ./script

然而,如果你想要掩盖 tr,你可以使用以下重定向将其默认嵌入到你的脚本中:

#!/usr/bin/env bash
exec 0< <( tr '[:upper:]' '[:lower:]' )
# the rest of your script comes here:
awk '...'

现在,您可以做这样的事情:

$ command | ./script

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