【问题标题】:calling awk on output of another script在另一个脚本的输出上调用 awk
【发布时间】:2016-02-28 23:32:07
【问题描述】:

我正在尝试使用 awk 在脚本的输出中搜索特定行。有人可以解释为什么这不返回输出:16.72

我的 bash 脚本:

speed=$(./speedtest-cli)
awk '/Download:/ {print $2}' $speed

speedtest-cli

pi@raspberrypi ~/Desktop/PiControl $ ./speedtest-cli
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Charter Communications (xxxxxx)...
Selecting best server based on latency...
Hosted by Charter Communications (yyyy, zz) [67.01 km]: 44.035 ms
Testing download speed........................................
Download: 16.72 Mbit/s
Testing upload speed..................................................
Upload: 3.45 Mbit/s

注意(包含在下面的 cmets 中)我试图避免使用单行,因为我计划从输出中打印多行。

编辑:

澄清我的最终目标。我正在尝试运行./speedtest-cli(我试图不更改此文件)。我正在尝试获取它的输出(下载速度、上传速度和延迟)并将它们作为单独的参数传递给另一个将它们写入数据库的脚本。 (本项目纯属个人使用......我不想在企业环境中使用它)

从上面的 speedtest-cli 输出我想这样做:

我的目标:

./another_script 16.72 3.45 44.035 

【问题讨论】:

  • 这只能在脚本中使用。
  • 抱歉,我编辑了我的帖子,以便更清楚地说明我是从 bash 脚本运行的
  • 单线试试:speedtest-cli | awk '{/Download:/} print $2'
  • 让您的 awk 脚本检索多个值,没问题。否则将输出保存到 tmp 文件,然后进行处理。当您使用 $speed (un-dbl-quoted) 时,shell 会将数据转换为一大组单词,而无需换行符分隔行。如果您使用set -vx 来调试/跟踪您的shell 脚本,您会看到这一点。祝你好运。
  • 请解释你的最终目标。您打算如何处理提取的值?收集解析这些数据的最佳方法可能取决于您打算如何处理它们。 (我在这里的建议是这是一个XY Problem,如果我们知道它是什么,我们可以帮助您更好地实现您的目标,而不是帮助您加速撞墙。)

标签: bash awk


【解决方案1】:

您的要求非常模糊(大局 - 您告诉我们您想如何做某事,而不是您想做什么)但也许这就是您想要的:

./speedtest-cli | awk -F': *' '/Download|Hosted by Charter Communications/{print $2}'
44.035 ms
16.72 Mbit/s

【讨论】:

  • 我在帖子中阐明了我的最终目标,希望对您有所帮助。
  • 当我在上面运行您的代码时,它只返回下载值(而不是两者),就像其他人可能对我的格式错误的问题所期望的结果感到困惑一样仅供参考。
  • 上面的正则表达式非常简单且可靠。如果您执行awk '/a|b/' file 并且它仅输出a 的匹配项,则输入文件中的b WAS NOT PRESENT
  • 将其写入文件后再次检查,您的正则表达式是正确的。
【解决方案2】:

首先,回答您的问题:

speed=$(./speedtest-cli)
awk '/Download:/ {print $2}' <<< "$speed"

其次,这几乎肯定不是您真正需要的。例如,您可以在 bash 中构造您想要的调用,然后使用 awk 的 system 函数,或者回显整个调用。

另一种方法是将感兴趣的值分配给 bash 数组,如下所示:

 a=( $(./speedtest-cli | awk -F ....) )

【讨论】:

    【解决方案3】:

    您已声明这是您的 bash 脚本:

    #!/bin/bash
    
    speed=$(./speedtest-cli)
    awk '/Download:/ {print $2}' $speed
    

    这失败了,因为你没有给 awk 解析任何东西。您正在设置一个变量以包含命令的输出,然后将该变量视为文件名。

    Awk 的命令行格式大致是这样的:

    awk [options] awkscript [file ...]
    

    $speed 是一个文件吗?不,不是。

    根据您对问题的编辑,看起来您想要做的只是去掉speedtest-cli 命令输出的数字。如果可以编辑可以采用这些数字的脚本,并且不需要您指定的顺序中的选项,那么最快的解决方案可能是这样的:

    /path/to/speedtest-cli | egrep -o '[0-9]+\.[0-9]+' | xargs /path/to/anotherscript
    

    这将获取speedtest-cli 的输出,去除所有非十进制数,然后将这些数字作为anotherscript 的选项。对于您提供的示例输入,这相当于运行

    anotherscript 67.01 44.035 16.72 3.45
    

    【讨论】:

    • 我喜欢这个解决方案,但是由于格式(12.34.56.12)作为前两个参数,它包含了ip地址xxxxx
    • 只要是一致的,你可以在anotherscript中说明,并且只使用你感兴趣的位置参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多