将上一个命令的输出作为参数传递给下一个

Pau*_*aul 179 command-line pipe command-substitution output arguments

我有一个将数据输出到 stdout ( command1 -p=aaa -v=bbb -i=4)的命令。输出行可以具有以下值:

rate (10%) - name: value - 10Kbps
Run Code Online (Sandbox Code Playgroud)

我想 grep 该输出以存储该“速率”(我想管道在这里会很有用)。最后,我希望该速率是第二个命令的参数值(假设command2 -t=${rate}

我这边看起来很棘手;我想更好地了解如何使用管道、grep、sed 等。

我已经尝试了很多这样的组合,但我对这些感到困惑:

$ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}
Run Code Online (Sandbox Code Playgroud)

jan*_*nos 197

您混淆了两种截然不同类型的输入。

  1. 标准输入 ( stdin)
  2. 命令行参数

这些是不同的,并且用于不同的目的。有些命令可以以两种方式接受输入,但它们通常以不同的方式使用它们。以wc命令为例:

  1. 通过以下方式传递输入stdin

    ls | wc -l
    
    Run Code Online (Sandbox Code Playgroud)

    这将计算输出中的行数 ls

  2. 通过命令行参数传递输入:

    wc -l $(ls)
    
    Run Code Online (Sandbox Code Playgroud)

    这将计算打印的文件列表中的行数ls

完全不同的东西。

要回答您的问题,听起来您想从第一个命令的输出中捕获速率,然后将该速率用作第二个命令的命令行参数。这是一种方法:

rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"
Run Code Online (Sandbox Code Playgroud)

的解释sed

  • s/pattern/replacement/命令是替换一些图案
  • 该模式的意思是:该行必须以“rate” ( ^rate) 开头,后跟任意两个字符 ( ..),后跟 0 个或多个数字,后跟 a %,后跟文本的其余部分 ( .*)
  • \1在替换中表示在 中捕获的第一个表达式的内容\(...\),因此在这种情况下,%符号之前的数字
  • 命令的-n标志sed表示默认不打印行。所述p在所述的端部s///指令装置打印的线,如果有一个更换。简而言之,该命令仅在匹配时才会打印一些内容。


Mic*_*son 65

我倾向于使用这个:

command1 | xargs -I{} command2 {}
Run Code Online (Sandbox Code Playgroud)

command1使用替换(大括号)将 through xargs 的输出传递给command2. 如果 command1find确保使用-print0并添加-0xargs空终止字符串,xargs并将调用command2找到的每个东西。

在您的情况下(并从@Janos 获取 sed 行):

command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p' | xargs -I{} command2 -t="rate was {}"
Run Code Online (Sandbox Code Playgroud)


小智 6

我通常使用“命令”将其输出作为另一个命令的参数。例如,在 freebsd 上查找进程 foo 消耗的资源将是:

procstat -r `pgrep -x foo`
Run Code Online (Sandbox Code Playgroud)

这里,pgrep 用于提取进程 foo 的 PID,该 PID 被传递给 procstat 命令,该命令需要进程的 PID 作为参数。


小智 5

为了模拟command1我使用这个 echo 语句的输出:

$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'
Run Code Online (Sandbox Code Playgroud)

快速测试:

$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag
Run Code Online (Sandbox Code Playgroud)

一切都很好,所以让我们解析它:

$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps
Run Code Online (Sandbox Code Playgroud)

所以我们得到了我们想要的行command1,让我们把它传递给command2

$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps
Run Code Online (Sandbox Code Playgroud)

我期待"rate was "$(command1 | grep 'rate')自动连接。如果由于空格而不起作用,您应该能够像这样传递输入:

$ alias command2='echo'
$ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"')
-t="rate was rate (10%) - name: value - 10Kbps "
Run Code Online (Sandbox Code Playgroud)


Gil*_*not 3

尝试一下:

command | grep -oP '\$>\s+rate\s+\(\K[^\)]+'
Run Code Online (Sandbox Code Playgroud)

  • 因此“grep”只会输出一些值,但问题是如何使用该值作为另一个命令的参数。不幸的是,您的答案中缺少这个重要部分。 (4认同)