我运行以下命令。
ps -e -o args | grep destiny | grep UNIX
我收到以下输出。
/path/to/destiny -r -m UNIX -t TCP -p 1501
我可以使用什么命令来获取打印参数的值(例如-m
or-t
或-p
)?我想实现以下目标。
ps -e -o args | grep destiny | grep UNIX | <someCommand> -p
这应该打印1501
ps -e -o args | grep destiny | grep UNIX | <someCommand> -m
这应该打印UNIX
ps -e -o args | grep destiny | grep UNIX | <someCommand> -t
这应该打印TCP
请注意,-p
、-m
或可能会切换列,因此无法-t
使用打印和按数字选择列。awk
更多事实使解析变得更容易(我知道我可能只是缺乏工具知识)。
- 如果选项不存在,将返回空字符串
- 在这种特殊情况下,将被解析的选项将始终有一个参数/值
答案1
这通常是不可能的,因为只有命令本身知道如何解析它自己的参数。以你的例子为例:
/path/to/destiny -r -m UNIX -t TCP -p 1501
-p
可以是一个不带参数的选项(如布尔值:它启用或禁用某些行为),在这种情况下1501
将是一个位置参数(如文件名或其他东西)。或者-p
可能是一个带有参数的选项,其参数是1501
。没有办法知道它是什么!
参数向量只是零个或多个字符串的列表。这些字符串没有附加任何含义,指示哪些是选项,哪些是这些选项的参数,哪些是非选项参数。
即使您示例中的选项也-r
无法进行一般性解析。鉴于-r
紧随其后的是另一个以 开头的字符串-
,这极有可能是-r
一个不带参数的选项(就像启用或禁用某些行为的布尔值),但实际上这并不是 100% 确定。-r
可以是一个带有参数的选项并且-m
将是它的参数。或者该命令可能根本不遵循正常的 UNIX 约定,并且-r
根本不是一个选项!
答案2
怎么样使用sed
:
ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-t\s\([A-Z0-9]*\).*/\1/'
ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-p\s\([A-Z0-9]*\).*/\1/'
ps -e -o args | grep -e 'destiny.*UNIX' | sed -e 's/.*-m\s\([A-Z0-9]*\).*/\1/'
sed -e 's/.*-t\s\([A-Z0-9]*\).*/\1/'
- s
search for
///replace with
options
- s 是搜索。
- .* 匹配任何/所有字符,直到我们到达“-t”。
- \s 匹配任何空格。
- ( 开始捕获。
- [A-Z0-9]* 匹配任意大写字母和任意长度的任意数字。
- ) 结束捕获。
- .* 匹配该行中的其余字符(如果有)。
- \1 用捕获替换所有内容。
答案3
您可以使用grep
:
~$ echo "/path/to/destiny -r -m UNIX -t TCP -p 1501" | grep -oP -- '-t \K[^ ]+'
TCP
~$ echo "/path/to/destiny -r -m UNIX -t TCP -p 1501" | grep -oP -- '-p \K[^ ]+'
1501
(您可能有/想要使用类似的东西\s
而不是一个空格grep -oP -- '-p\s\K[^\s]+'
:)
意思-o
是“只打印匹配的”,\K
将会重置开始。
请注意,这只会处理简单的情况(请参阅塞拉达的答案)。
另一种方式,使用后视:
grep -oP -- '(?<=-p )[^ ]+'
答案4
这是一个Python单行代码。 (我使用 python 是因为 perl 和 awk 没有简单的方法来获取列表中值的位置。)
ps -eo args | grep '/path/to/destiny' |
python -c 'x=input().split(); print(x[ x.index("-p")+1 ])'
只要您尝试提取的参数不包含空格,它就可以工作。