【问题标题】:Issues passing AWK output to BASH Variable将 AWK 输出传递给 BASH 变量的问题
【发布时间】:2016-02-09 15:00:28
【问题描述】:

我正在尝试从 BASH 中的错误日志中解析行,然后将某个部分发送到 BASH 变量,以便稍后在脚本中使用,并且在尝试将其传递给 BASH 变量时遇到问题。

日志文件的样子:

1446851818|1446851808.1795|12|NONE|DID|8001234

我需要该行的第三组(在本例中为 12)中的数字

这是我正在运行的命令的示例:

tail -n5 /var/log/asterisk/queue_log | grep 'CONNECT' | awk -F '[|]' '{print $3}'

该行代码正在尝试完成此操作:

  1. 获取日志文件的最后几行
  2. 搜索一个短语(在本例中为连接,我使用相同的命令来触发不同的项)
  3. 将第三组中的数字分开,以便在其他地方使用

如果我运行上面的完整命令,它会像这样成功运行:

tail -n5 /var/log/asterisk/queue_log | grep 'CONNECT' | awk -F '[|]' '{print $3}'
12

现在,如果我尝试将它分配给同一行/命令中的变量,我无法让它回显该变量。

分配给变量时的命令如下所示:

tail -n5 /var/log/asterisk/queue_log | grep 'CONNECT' | brand=$(awk -F '[|]' '{print $3}')

(它与 echo 命令在同一脚本中运行,因此变量应该没问题,测试脚本如下所示:

#!/bin/bash
tail -n5 /var/log/asterisk/queue_log | grep 'CONNECT' | brand=$(awk -F '[|]' '{print $3}')
echo "$brand";

我知道这很可能不是最有效/最有说服力的解决方案,所以如果有其他想法/方法可以实现这一点,我也愿意接受他们(我的 BASH 技能是基本的,但正在改进)

【问题讨论】:

  • 不是foo | x=$(bar),而是x=$(foo | bar)。
  • 管道的右侧在子外壳中运行,因此当管道的那一侧退出时,在那里所做的更改会丢失:x=hello; echo good-bye | read x; echo $x 将输出 hello,而不是 good-bye。

标签: linux bash shell awk


【解决方案1】:

您需要捕获整个管道的输出, 而不仅仅是它的最后一部分:

brand=$(tail -n5 /var/log/asterisk/queue_log | grep 'CONNECT' | awk -F '|' '{print $3}')

您可能还想考虑如果在文件的最后五行中有不止一行包含CONNECT(或者实际上,如果没有)会发生什么。这将导致brand 具有多个(或没有)值。


如果您的意图是从包含CONNECT 的文件的最新行中获取第三个字段,awk 几乎可以处理整个事情,而无需tail 或grep:

brand=$(awk -F '|' '/CONNECT/ {latest = $3} END {print latest}')

【讨论】:

  • 对也输了grep:tail ... | awk -F '|' '/CONNECT/{print $3}'
  • @Ed,我想过这一点,但只看最后五行的混乱让我停了下来。但是,我根据您的评论添加了一个建议,表明与 OP 要求的略有不同,当然,这并不总是他们想要的:-)
  • Re:搜索中的行数,我的 Live Copy 将其设置为 -n1,因为它使用 inotifywait 并在文件被修改时立即检查文件,我是手动运行的,最后一个日志条目适用的短语大约有 4 行,所以我只是快速修改它以便手动测试/运行。
  • @paxdiablo 我并不是在建议摆脱尾巴,只是 grep。如果 CONNECT 在最后 5 行中多次出现(第一次?最后一次?全部?),我真的不确定 OP 会想要什么
猜你喜欢
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 2013-10-10
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多