次のように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」のみを取得するにはどうすればよいですか?
awk
の場合:
ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'
表示されているエラーメッセージは表示されていませんが、おそらく
grep:不明なデバイスのメソッド
これは、他のすべてのコマンドラインプログラムと同様に、grep
は-
で始まるものはすべてオプションであると想定し、そのように解析しようとするためです。この場合、-D
を使用して、grep
にデバイスファイルの処理方法を指示します(詳細については、man grep
を参照してください)。これを回避する1つの方法は、--
を使用することです。これはgrep
に、後続のすべてがオプションフラグではないことを伝えます。
これをGNU grep
のPCRE機能と組み合わせると、次のことができます。
ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'
正規表現は-
を検索して破棄し(\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]+')"
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'
他の回答よりも複雑ですが、これはgetopt
を使用して解析を処理します。さらに別の選択肢。
_getopt -aql 'Dapp.name:' $(\
ps -af -u sas | grep Java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
_
ps -af -u sas | grep Java | grep -v grep
_tr -s ' '
_ cut
の準備として、複数のスペースを1つのスペースに「圧縮」します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
_です。getopts -aql 'Dapp.name:' $(...)
は、コマンドオプションを解析し、値が_Dapp.name
_である_:
_に一致するロングネームのみを出力します。結果は_--Dapp.name 'myApp' --
_です。cut -d"'" -f2
_は一重引用符で囲まれていますmyApp
ps … | grep …
を使用していて、結果からgrepを除外する必要があるときはいつでも、間違っています。
ps
の出力を解析する0番目のルールは、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'
私は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+"