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
strugee

grep [j]avaコマンドを回避するために使用できますgrep -v "grep"(bashでテスト)
HVNSweeting

回答:



8

表示されているエラーメッセージは表示されていませんが、おそらく

grep:不明なデバイスのメソッド

これは、他のすべてのコマンドラインプログラムgrepと同様に、aで始まるものはすべて-オプションであると想定し、そのように解析しようとするためです。この場合-Dgrep、デバイスファイルの処理方法を指示するために使用されます(詳細はman grepを参照)。これを回避する1つの方法は、を使用--する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]+')"


3

ps … | grep …結果からgrepを除外する必要があるときはいつでも、それは間違っています。

の出力を解析する第0の規則はpspgrep可能であれば、より信頼性の高いツールを使用することです。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を含むすべてのフィールドを取得します。結果は /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+"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.