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
您混淆了两种截然不同类型的输入。
stdin)这些是不同的,并且用于不同的目的。有些命令可以以两种方式接受输入,但它们通常以不同的方式使用它们。以wc命令为例:
通过以下方式传递输入stdin:
ls | wc -l
Run Code Online (Sandbox Code Playgroud)
这将计算输出中的行数 ls
通过命令行参数传递输入:
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) 开头,后跟任意两个字符 ( ..),后跟 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并添加-0到xargs空终止字符串,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)
command | grep -oP '\$>\s+rate\s+\(\K[^\)]+'
Run Code Online (Sandbox Code Playgroud)