如何从ps命令中提取键值对


10

我试图从这样的ps命令中提取应用程序名称:

ps -af -u sas |grep "java"| grep -v "grep"

并产生以下结果:

sas 24431     1  0 Oct10 ?        00:51:08 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs

我尝试使用,egrep但似乎无法正常工作:

ps -af -u sas|grep "java"| grep -v "grep"| egrep -o "-Dapp.name"

如何仅获-Dapp.name取值“ myApp”?


如果grep模式以开头-,则需要将其放在-e选项之后。否则,它将被视为选项。但这只会匹配单词-Dapp.name,而不是其后的部分。
Barmar 2014年

交替:grep -o -- -Dapp.name
2014年

您可以grep [j]ava用来避免命令grep -v "grep"(经过bash测试)
HVNSweeting 2014年

Answers:


7

awk

ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'

8

您没有显示错误消息,但可能是

grep:未知设备方法

这是因为,与所有或至少大多数其他命令行程序一样,grep假定以a开头的任何内容-都是一个选项,并尝试以此方式进行解析。在这种情况下,-D用于指示grep如何处理设备文件(man grep有关详细信息,请参阅)。解决该问题的一种方法是使用--,该方法告诉grep所有后面的内容都不是选项标志。

结合使用GNU的PCRE功能grep,您可以执行以下操作:

ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'

正则表达式先搜索a -并丢弃它(\K),然后是字符串,Dapp.name=后跟尽可能多的非空格字符。输出为:

Dapp.name=myApp

如果您希望将myApp零件保存在变量中,我将单独搜索:

ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+'

要将其分配给变量:

$ app="$(ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+')"
$ echo $app
myApp

但是,永远不要grep输出ps此类内容,这pgrep是为了:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"

4
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'

3

任何时候使用ps … | grep …并且需要从结果中排除grep的做法,都是错的。

解析输出的第零条规则ps是使用更可靠的工具(如pgrep可用)。如果您有pgrep,则pgrep -f java列出所有运行命令的进程java。该选项-l为每个进程添加命令行。

要提取的参数-Dapp.name,可以使用sed。匹配整行,安排将有趣的部分填充到组中,然后打印出该组。

pgrep -lf java | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

解析输出的第一个规则ps是使用选项-o选择所需的字段。在这里,您仅对命令参数感兴趣,因此仅打印该参数。

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

3

比其他答案更复杂,但这getopt用于为您处理解析。另一个选择。

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. 您的命令: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' 准备将多个空间“压缩”到一个空间中 cut
  3. cut -d' ' -f8- 用空格分割线,并在8个端点(含8个)之后获取所有字段,结果是 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs
  4. getopts -aql 'Dapp.name:' $(...)解析命令选项,仅输出与Dapp.name具有值的谁匹配的长名(由表示:),结果为--Dapp.name 'myApp' --
  5. cut -d"'" -f2 抓住单引号中的内容
  6. 结果是: myApp

0

我会用pgrep而不是ps这样:

$ pgrep -fa java | grep -op "(<=-Dapp.name=)\w+"

这将返回所有匹配的进程,java然后将其过滤掉,仅显示包含的进程-Dapp.name=。最后一位\w+将显示程序名称,假定它不包含空格。

注:-P开关grep报名指定使用的东西的能力PCRE - Perl兼容的正则表达式。并非所有版本都grep支持它,但大多数更新版本都包含在Linux中。

如果您想要整个键/值输出,请进行如下更改:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.