【问题标题】:Using a pipe to input in an awk statement使用管道输入 awk 语句
【发布时间】:2014-11-25 02:32:19
【问题描述】:

所以我正在处理一个名为汽车的文件,这是它的内容:

toyota corolla 1970 2500
chevy malibu 1999 3000
ford mustang 1965 10000
volvo s80 1998 9850
ford thundbd 2003 10500
chevy malibu 2000 3500
honda civic 1985 450
honda accord 2001 6000
ford taurus 2004 17000
toyota rav4 2002 750
chevy impala 1985 1550
ford explor 2003 9500

我正在使用 grep 过滤包含特定汽车制造商的行,然后将其传送到我的 awk 语句,最后将最终结果传送到带有 tee 的新管道。

这是我遇到问题的代码行:

grep "$model" cars | 
   awk '($3+0) >= ("'$max_year'"+0) && ($4+0) <= ("'$max_price'"+0)' | 
     tee last_search

我之前在脚本中将变量 max_year 和 max_price 定义为用户输入。

文件 last_search 已创建,但始终为空。

【问题讨论】:

  • $max_year$max_price 是什么?你可能会更好地使用-v max_year="$max_year"等,然后在awk中使用max_year等,而不需要玩报价游戏。在几乎所有情况下grep | awk 都是不必要的,因为您可以直接在awk 中进行相同的过滤。
  • 我之前在脚本中定义了变量 max_year 和 max_price 作为用户输入。
  • Etan 表示 awk -v max_year="$max_year" -v max_price="$max_price" 然后丢失 awk 代码块中所有无关的引号 - { } 字符内的部分。跨度>

标签: linux bash awk pipe


【解决方案1】:

您几乎可以肯定您的变量有问题,您应该将它们打印出来并逐步构建管道,一次一个命令进行调试。

就目前而言,它适用于以下值:

$ max_year=2000
$ max_price=10000
$ model=a

$ grep "$model" cars
toyota corolla 1970 2500
chevy malibu 1999 3000
ford mustang 1965 10000
chevy malibu 2000 3500
honda civic 1985 450
honda accord 2001 6000
ford taurus 2004 17000
toyota rav4 2002 750
chevy impala 1985 1550

$ grep "$model" cars | awk '($3+0) >= ("'$max_year'"+0) && ($4+0) <= ("'$max_price'"+0)'
chevy malibu 2000 3500
honda accord 2001 6000
toyota rav4 2002 750

还有更好的方法可以做到这一点,而不必像以前那样管理命令字符串,因为它可能容易出错。您可以使用:

grep "$model" cars |
  awk -vY=$max_year -vP=$max_price '$3>=Y&&$4<=P{print}'

(你会注意到我没有使用 string+0 技巧,GNU awk,你几乎可以肯定在 Linux 下使用它,处理得很好,如果两个参数都是数字,它将在数字上进行比较自然)。

【讨论】:

  • 我相信你可以在这个解决方案中删除grep
  • @Jotne,如果您想要与原始版本相同的功能,例如搜索 make or 模型,或寻找 al 以获得 Malibu ,则不是和 Impala,&lt;space&gt;m[au] 用于野马 Malibu,甚至使用. 来获得所有汽车。这就是为什么我对 Steven 的回答不那么热衷的原因,因为它将解决方案锁定为只匹配完整的模型名称,尽管这还不足以推翻我的公平感并给他投反对票,当然 :-)
  • awk 可以像 grep 一样执行非锚定的非特定字段匹配。你不能匹配一个词作为品牌或型号?在 awk 脚本中使用 -v model="$model" and then $0 ~ model`。 /al// m[au]/ 相同。但是,如果您对模式使用字符串文字,则必须正确考虑引用差异。
【解决方案2】:
set -a
model=malibu
max_year=2000
max_price=4000

awk '
$2 == ENVIRON["model"] &&
$3 >= ENVIRON["max_year"] &&
$4 <= ENVIRON["max_price"]
' cars |
tee last_search

【讨论】:

  • 您能否进一步详细说明以帮助 Bob 了解他哪里出错了?
猜你喜欢
  • 1970-01-01
  • 2020-05-08
  • 2011-10-18
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多