Awk AND 运算符

21

关于AND逻辑运算符的一个基本问题。我想根据第一列和第二列的值从我的数据文件niveles.csv中提取一些字段。我想编写一个awk语句,可以说“当field1 = date且field2 = area时,打印第3到5个字段”。

我的数据文件看起来像

01-08-12;1;0;0;0
01-08-12;2;1;1;1
01-08-12;3;0;0;1
................

在 bash 脚本中,awk 语句是

date=01-08-2012
area=8
awk 'BEGIN {FS=";"}  $1 ~ /'$date'/ && $2 ~ /'$area'/ { print $1 " " $2 " "  $3 " " $4 " " $5 }' niveles-rams.cs

但这只是提供了包含数字8的三种情况的字段(8、18和28),而我只想要区域8的数据。

01-08-2012 8 0 0 0
01-08-2012 18 2 2 1
01-08-2012 28 2 1 0

感谢您的关注,对于有经验的用户来说这是一个简单的问题。

4个回答

17

未经过测试:

awk 'BEGIN {FS=";"}  $1 ~ /'$date'/ && $2 == '$area'{......}'

$2 ~ /8/ 表示如果第二个字段包含8。

$2 == 8 表示如果第二个字段等于8。


谢谢,我之前不知道~和==之间的区别。 - pacomet
4
不要这样做!参见http://cfajohnson.com/shell/cus-faq-2.html#Q24以了解如何从awk脚本中访问shell变量的值,并查看@Barmar在此处的答案。 - Ed Morton
@EdMorton: 我同意这不是正确访问shell变量的方式……提供的解决方案是为了使原帖作者的解决方案正常工作…… - Guru
3
虽然加密方法不会突然失效,但是给他一个从根本上不会出现加密失败的解决方案不是更好吗? - Ed Morton

13

由于这个问题因标题而受到很多关注,让我发一篇更通用的答案,介绍如何在 awk 中使用 AND 运算符。

假设你有一个文件myfile

a 1 2 3
b 4 5 6
c 7 8 9

如果你想使用 AND 运算符进行多个检查,你需要像这样使用 &&

awk '$2 < 10 && $3 > 2' myfile

这将返回:

b 4 5 6
c 7 8 9

通常情况下,您可以使用任意多个条件,需要考虑到:


AND --> &&
OR  --> ||

因此,您可以像以下示例一样组合多个逻辑表达式:

awk '($2 < 10 || $3 > 2) && ($2 > 10 || $3 < 2)' myfile
#    ^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^

11

使用awk的-v选项来创建包含shell变量的awk变量。

awk -v date="$date" -v area="$area" '$1 == date && $2 == area { ... }'

0

这应该没问题,我进行了一些测试:

date="01-08-12"
area=8
awk -F\; '$1 == "'$date'" && $2 == '$area' { print $3 " " $4 " " $5 }' niveles-rams.csv

如果您想在其中包含日期和区域字段,则awk语句如下:
awk -F\; '$1 == "'$date'" && $2 == '$area' { print $1 " " $2 " " $3 " " $4 " " $5 }' niveles-rams.csv

1
不要这样做!请参考cfajohnson.com/shell/cus-faq-2.html#Q24以了解如何从awk脚本中访问shell变量的值,并查看@Barmar在此处的答案。 - Ed Morton
你可以使用 -awk -F\; -vOFS=' ' '$1 == "'$date'" && $2 == '$area' { print $3, $4, $5 }' niveles-rams.csv,对此我不做其他评论,因为我不是 awk 专家,我只是注意到了 OFS 变量很酷,它可以代替在引号中添加所有空格。 - xenoterracide

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