bash - AWK 中的条件
问题描述
我正在使用awk
(MacOS 上的版本 20070501)过滤一些数据,但在将多个否定匹配条件应用于特定列中的值时遇到了语法挑战。
这是一个我认为可以解决我的问题的通用示例。
输入:
foo,bar
bar,foo
foo,bar
bar,foo
foo
使用此代码,我删除了第 2 列中的匹配项:
awk 'BEGIN { FS=OFS="," } ; { if ($2 !~ /foo/ ) print $0}'
我得到了这个输出,这是我所期望的:
foo,bar
foo,bar
接下来,我在语句中添加一个附加条件,以同时删除第 2 列中if
匹配的所有值:bar
awk 'BEGIN { FS=OFS="," } ; { if ($2 !~ /foo/ || $2 !~ /bar/) print $0}'
我得到了这个输出,这是我没想到的:
foo,bar
bar,foo
foo,bar
bar,foo
我预计不会返回任何行,这是我的目标。发生什么了?
这两个条件是否相互抵消?我阅读了布尔表达式的 GNU awk 文档,其中指出:
'&&' 和 '||' 运算符因其工作方式而被称为短路运算符。如果结果可以在其评估的中途确定,则对完整表达式的评估是“短路的”。
从这个片段中,我不确定如何取得进展。还是语法不正确的问题?或两者?
更新:
在@wiktor-stribiżew 的评论和帮助之后,这里更好地表示了这个问题:
1 2 3 4 5
foo bar foo bar FY 2008 Program Totals
foo bar foo bar FY 2009 Program Totals
foo bar foo bar Fiscal Year 2010 Program Totals
foo bar foo bar Fiscal Year 2011 Program Totals
foo bar foo bar Fiscal Year 2012 Program Totals
foo bar foo bar Fiscal Year 2013 Program Totals
foo bar foo bar Fiscal Year 2014 Program Totals
foo bar foo bar Fiscal Year 2015 Program Totals
foo bar foo bar Fiscal Year 2016 Program Totals
foo bar foo bar Fiscal Year 2017 Program Totals
我失败的代码是:
awk 'BEGIN { FS=OFS="\t" } ; { if ($5 !~ /Fiscal.*Program Totals/ || $5 !~ /FY.*Program Totals/) print $0}'
下面接受的答案解决了这个问题。
解决方案
您想过滤掉字段 2 与foo
or匹配的行bar
,因此您希望该字段不等于foo
and bar
。因此,您需要&&
运算符:
awk -F',' '$2 !~ /foo/ && $2 !~ /bar/' file > newfile
# ^^
||
请注意,如果您对条件进行分组并否定结果,您也可以使用:
awk -F\, '!($2 ~ /foo/ || $2 ~ /bar/)' file > newfile
请注意,您不需要设置OFS
,因为您只打印$0
(整行)并且由于它是默认操作,如果您编写如上所示的条件,则无需指定。
推荐阅读
- ios - 由于 ajax 请求,React Native 三元运算符显示滞后
- scala - 如何使用 akka typed 解决 akka.stream.Graph 接收器错误 akka 流
- android - Firebase Crashlytics 不显示事件日志
- javascript - 将操作从 nemespaced vuex 模块映射到组件方法仅适用于 2 种可用语法之一
- python - 为什么'type()'函数没有返回任何东西?
- html - CSS:位置:绝对内部位置:相对未正确定位在溢出-x:可见
- python - 你如何在python中合并两个列表
- javascript - 将状态变量作为参数的 React 组件不会在更新时呈现
- javascript - 在反应js中重定向到主页
- sql - 使用 Pivot 在 SQL Server 中将行转换为列