command1 -p=aaa -v=bbb -i=4
)。输出行可以具有以下值:为了存储该“速率”(我想管道在这里很有用)。
最后,我希望该速率成为第二个命令上的参数值(比如说
command2 -t=${rate}
)在我这边看起来很棘手;我想更好地了解如何使用管道,grep,sed等。
我已经尝试了很多类似的组合,但是我对这些组合感到困惑:
rate (10%) - name: value - 10Kbps
#1 楼
您正在混淆两种非常不同的输入类型。标准输入(
stdin
)命令行参数
它们是不同的,并且对于不同的目的。某些命令可以通过两种方式获取输入,但是它们通常以不同的方式使用它们。以
wc
命令为例:stdin
传递输入:在ls
的输出中通过命令行参数传递输入:
ls | wc -l
这将计算文件列表中的行由
ls
打印完全不同的东西。然后将rate用作第二个命令的命令行参数。这是执行此操作的一种方法:
wc -l $(ls)
sed
的解释: br />模式表示:该行必须以“ rate”(s/pattern/replacement/
)开头,后跟任意两个字符(^rate
),然后是0个或多个数字,然后是..
,然后是其余文本(%
) br /> 替换中的
.*
表示在
中捕获的第一个表达式的内容,因此,在这种情况下,\(...\)
符号前面的数字。 %
命令末尾的-n
表示如果有替换,则打印该行。简而言之,该命令仅在匹配时才打印某些内容。#2 楼
我倾向于使用它:command1 | xargs -I{} command2 {}
通过xargs使用替换(花括号)将
command1
的输出传递给command2
。如果command1是find
,请确保使用-print0
并将-0
添加到xargs
中以终止的字符串为空,并且xargs
将为找到的每一个调用command2
。 command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*//p' | xargs -I{} command2 -t="rate was {}"
#3 楼
为了模拟command1
的输出,我正在使用以下echo语句:$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'
快速测试:
$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag
这一切都很好,所以让我们解析一下: br />
$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps
我希望
command1
自动连接。如果由于空白而不能工作,那么您应该能够像这样传递输入:
$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps
#4 楼
使用grep和pcre尝试以下操作:command | grep -oP '$>\s+rate\s+\(\K[^\)]+'
评论
所以grep只会输出一些值,但问题是如何使用该值作为另一个命令的参数。不幸的是,您的答案中缺少该重要部分。
– David FerenczyRogožan
19-10-31在17:05
#5 楼
第一项任务是从那条线中提取速率。使用GNU grep(非嵌入式Linux或Cygwin),可以使用-o
选项。所需的部分是仅包含数字的部分,后跟一个%
符号。如果您不想提取%
本身,则需要一个额外的技巧:零宽度超前断言,它仅与%
不匹配,但不匹配。command1 -p=aaa -v=bbb -i=4 | grep -o -P '[0-9]+(?=%)'
另一种可能性是使用sed。要提取sed中的行的一部分,请使用
s
命令,并使用与整个行匹配的正则表达式(以^
开头并以$
结束),并将该部分保留在组中(\(…\)
)。将整个行替换为要保留的组的内容。通常,传递-n
选项以关闭默认打印,然后将p
修饰符打印到要提取某些内容的行(这里只有一行,所以没关系)。有关更多sed技巧,请参见仅返回匹配模式之后的行的一部分,并提取与'sed'匹配的正则表达式而不打印周围的字符。command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$//'
更灵活比sed再一次,是awk。 Awk用一种小的命令式语言为每一行执行指令。这里有很多方法可以提取费率;我选择第二个字段(默认情况下字段由空格分隔),并删除其中的所有非数字字符。
command1 -p=aaa -v=bbb -i=4 | awk '{gsub(/[^0-9]+/, "", ); print }'
既然您已经提取了速率,下一步就是将其作为参数传递给
command2
。用于此目的的工具是命令替代。如果在$(…)
(美元括号)中放入命令,则其输出将替换为命令行。命令的输出在每个空格块处分为多个单独的单词,每个单词均被视为通配符模式;除非您希望这种情况发生,否则在命令替换处用双引号引起来:"$(…)"
。使用双引号将命令的输出直接用作单个参数(唯一的转换是删除了输出末尾的换行符)。command2 -t "$(command1 -p=aaa -v=bbb -i=4 |
sed 's/^.*rate(\([0-9]*\)%).*$//')"
#6 楼
我通常使用`command`将其输出作为另一个命令的参数。例如,要查找freebsd上进程foo消耗的资源,将是:procstat -r `pgrep -x foo`
此处,pgrep用于提取进程foo的PID,该PID传递给procstat命令期望将过程的PID作为参数。
#7 楼
您可以使用grep
及其PCRE-Perl兼容的正则表达式。这样一来,您便可以利用后置匹配来匹配rate的值,而在对其进行grepping时不会在结果中包含字符串“ rate”。 /> 详细信息
上面的
grep
的工作方式如下: -o
启用grep的PCRE功能\d+
将仅返回以“ rate(” < command2 要捕获“ rate”的值,您可以像这样运行
-P
:使用该变量。$ echo "rate (10%) - name: value - 10Kbps" | grep -oP '(?<=^rate \()\d+'
10
你可能会喜欢上所有一行:
$ rate=$(command 1 | grep -oP '(?<=^rate \()\d+'
(?<=^rate \()执行块内执行command1,获取结果并将其包含在command2的
command1
开关中。
评论
这样可以使事情变得井井有条,这就是为什么我喜欢这一点。
–玛蒂·乌尔哈克
19年5月13日在9:04