【问题标题】:using awk with column value conditions将 awk 与列值条件一起使用
【发布时间】:2013-01-22 05:46:39
【问题描述】:

我正在向 The AWK Programming Language 学习 awk,但其中一个示例有问题。

如果我想在 $2 等于一个值时打印 $3(例如1),我使用的这个命令可以正常工作:

awk '$2==1 {print $3}' <infile> | more

但是当我用另一个搜索条件(例如findtext)替换 1 时,该命令不起作用:

awk '$1== findtext {print $3}' <infile> | more

它不返回任何输出,我确定输入文件中存在“findtext”。

这个我也试过了,还是不行:

awk '$1== "findtext" {print $3}' <infile> | more

这是我的名为“test”的测试文件,它有 9 行和 8 个字段,以空格分隔:

1 11 0.959660297 0 0.021231423 -0.0073 -0.0031 MhZisp
2 14 0.180467091 0.800424628 0 0.0566 0.0103 ClNonZ
3 19 0.98089172 0 0 -0.0158 0.0124 MhNonZ
4 15 0.704883227 0.265392781 0.010615711 -0.0087 -0.0092 MhZisp
5 22 0.010615711 0.959660297 0.010615711 0.0476 0.0061 ClNonZ
6 23 0.715498938 0 0.265392781 -0.0013 -0.0309 Unkn
7 26 0.927813163 0 0.053078556 -0.0051 -0.0636 MhZisp
8 44 0.55626327 0.222929936 0.201698514 0.0053 -0.0438 MhZisp
9 31 0.492569002 0.350318471 0.138004246 0.0485 0.0088 ClNonZ

这是我所做的和输出:

$awk '$8 == "ClNonZ" {print $3}' test 

$ grep ClNonZ test 
2 14 0.180467091 0.800424628 0 0.0566 0.0103 ClNonZ
5 22 0.010615711 0.959660297 0.010615711 0.0476 0.0061 ClNonZ
9 31 0.492569002 0.350318471 0.138004246 0.0485 0.0088 ClNonZ

我希望看到这是 3 美元,其 8 美元中有“ClNonZ”。

0.180467091 
0.010615711 
0.492569002

不知道为什么 awk 命令没有返回任何内容。有什么想法吗?

【问题讨论】:

  • 需要把字符串值“findtext”引用起来,否则是变量名
  • 我用“findtext”尝试了双引号,但它不起作用..这就是它困扰我的原因
  • “不起作用”并没有告诉我们任何事情。向我们展示准确的输入、准确的代码、预期的输出和实际的输出。

标签: linux shell awk


【解决方案1】:

如果您要查找特定字符串,请在其周围加上引号:

awk '$1 == "findtext" {print $3}'

否则,awk 将假定它是一个变量名。

【讨论】:

  • 我试过了,但它不起作用我不知道为什么。我用 grep 仔细检查了,文本就在那里。 :(
  • @user1687130,我认为您需要向我们展示一些示例输入和预期输出。
  • 您确定您的数据是空格分隔的吗?其中一些空间可能是制表符吗?尝试使用 awk 来回显单个字段。 awk '{ print $8 }' 能满足你的期望吗?
  • 这可能是由于AWK 实现(使用awk --version 检查),看看我的回答,它也适用于GAWKMAWK
  • 当我们在 awk 脚本周围使用双引号时,这不起作用。喜欢awk "$1 == \"findtext\" {print $3}"
【解决方案2】:

此方法使用正则表达式,它应该可以工作:

awk '$2 ~ /findtext/ {print $3}' <infile>

【讨论】:

  • 谢谢我正在寻找一种方法来使用 awk 来查找 $NF 上的正则表达式,而不使用恶魔方法和 grep ^^
【解决方案3】:

根据AWK 的实现,您是否使用== 是否正常。

你试过~吗?例如,如果你想让 $1 成为“你好”:

awk '$1 ~ /^hello$/{ print $3; }' <infile>

^ 表示 $1 开始,$ 表示 $1 结束。

【讨论】:

  • 所有 awk 实现都支持 "==" 和 "~"。
  • @EdMorton - OS X 的awk== 匹配失败,但与~ 匹配成功。
  • @jww 匹配什么和什么失败?它们是等效的:$1 == "hello"$1 ~ /^hello$/。你永远不应该这样做 $1 ~ "^hello$" 如this answer所示,因为它在正则表达式上下文中使用字符串,因此 awk 必须在使用它之前将字符串转换为正则表达式并且有副作用(man awk)。
【解决方案4】:

这对我来说更具可读性

awk '{if ($2 ~ /findtext/) print $3}' <infile>

【讨论】:

    【解决方案5】:

    我的 awk 版本是 3.1.5。

    是的,输入文件是空格分隔的,没有制表符。

    根据 arutaku 的回答,这是我尝试过的有效方法:

    awk '$8 ~ "ClNonZ"{ print $3; }' test  
    0.180467091
    0.010615711
    0.492569002
    
    
    $ awk '$8 ~ "ClNonZ" { print $3}' test  
    0.180467091
    0.010615711
    0.492569002
    

    什么不起作用(我不知道为什么,也许是因为我的 awk 版本:),

    $awk '$8 ~ "^ClNonZ$"{ print $3; }' test
    $awk '$8 == "ClNonZ" { print $3 }' test
    

    感谢大家的回答、cmets 和帮助!

    【讨论】:

    • 这与你的 awk 版本无关。您在 Windows 上创建了测试文件,因此无论您使用什么工具将 control-M 附加到每行的末尾,因此每行的最后一个字段是 ClNonZ&lt;control-M&gt;,而不是 ClNonZ,这就是为什么 RE 部分匹配比较为在 awk 中使用 grep 或 "~" 可以找到它,但相等比较不会。
    • 是的,有道理。我尝试了 $dos2unix test 然后使用“==”替换“~”并且它有效。谢谢你的解释!
    【解决方案6】:

    请试试这个

    echo $VAR | grep ClNonZ | awk '{print $3}';
    

    echo cat filename | grep ClNonZ | awk '{print $3}';
    

    【讨论】:

    • 遗憾的是,这个答案实际上并没有使用用户特别要求的 Awk 语法!
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    相关资源
    最近更新 更多