So extrahieren Sie ein Schlüsselwertpaar aus dem Befehl ps

10

Ich versuche, den Anwendungsnamen pswie folgt aus dem Befehl zu extrahieren :

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

und es erzeugt Folgendes:

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

Ich habe es versucht, egrepaber es scheint nicht zu funktionieren:

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

Wie kann ich nur den -Dapp.nameWert "myApp" erhalten?

Sas
quelle
Wenn das grepMuster mit beginnt -, müssen Sie es nach der -eOption einfügen. Andernfalls wird es als Option behandelt. Aber das passt nur zum Wort -Dapp.name, nicht zum Teil danach.
Barmar
alternativ:grep -o -- -Dapp.name
strugee
Sie können verwenden grep [j]ava, um Befehl zu vermeiden grep -v "grep"(auf Bash getestet)
HVNSweeting

Antworten:

7

Mit awk:

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

Sie zeigen nicht die Fehlermeldung an, die Sie erhalten, aber es ist wahrscheinlich

grep: Methode für unbekannte Geräte

Dies liegt daran, dass, wie bei allen oder zumindest den meisten anderen Befehlszeilenprogrammen, grepdavon ausgegangen wird, dass alles, was mit a beginnt, -eine Option ist, und versucht, es als solches zu analysieren. In diesem Fall -Dwird verwendet, um Anweisungen grepzum Umgang mit einer Gerätedatei zu erhalten ( man grepEinzelheiten siehe ). Eine Möglichkeit, dies zu --umgehen grep, besteht darin, zu verwenden , dass alles, was folgt, kein Optionsflag ist.

Wenn Sie dies mit der PCRE-Fähigkeit von GNU kombinieren grep, können Sie Folgendes tun:

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

Der reguläre Ausdruck sucht nach a -und verwirft es ( \K), dann die Zeichenfolge, Dapp.name=gefolgt von so vielen Nicht-Leerzeichen wie möglich. Die Ausgabe ist:

Dapp.name=myApp

Wenn Sie möchten, dass das myAppTeil in einer Variablen gespeichert wird, würde ich allein danach suchen:

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

So weisen Sie es einer Variablen zu:

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

Sie sollten jedoch niemals grepdie Ausgabe psfür so etwas machen, dafür pgrepist es da:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"
terdon
quelle
4
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'
Barmar
quelle
3

Jedes Mal, wenn Sie ps … | grep …grep verwenden und von den Ergebnissen ausschließen müssen, machen Sie es falsch.

Die nullte Regel beim Parsen der Ausgabe von psbesteht darin, zuverlässigere Tools zu verwenden, z. B. pgrepfalls verfügbar. Wenn Sie pgrep haben, werden pgrep -f javaalle Prozesse aufgelistet, die den Befehl ausführen java. Die Option -lfügt die Befehlszeile für jeden Prozess hinzu.

Um das Argument zu extrahieren -Dapp.name, können Sie sed verwenden. Passen Sie die gesamte Zeile an, arrangieren Sie das Füllen des interessanten Teils in einer Gruppe und drucken Sie diese Gruppe aus.

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

Die erste Regel zum Parsen der Ausgabe von psbesteht darin, die Option -ozu verwenden, um die Felder auszuwählen, die Sie benötigen. Hier interessieren Sie nur die Befehlsargumente, drucken Sie also nur diese aus.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'
Gilles 'SO - hör auf böse zu sein'
quelle
3

Komplizierter als die anderen Antworten, aber dies wird verwendet getopt, um das Parsen für Sie zu erledigen. Noch eine Alternative.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. Ihr Befehl: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "quetscht" mehrere Räume in einen einzigen Raum, um sich darauf vorzubereiten cut
  3. cut -d' ' -f8- teilt die Zeile durch Leerzeichen und erfasst alle Felder nach 8 einschließlich, Ergebnis ist /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:' $(...)analysiert die Befehlsoptionen und gibt nur den Langnamen aus, Dapp.nameder mit dem Wert übereinstimmt (gekennzeichnet durch :). Das Ergebnis ist--Dapp.name 'myApp' --
  5. cut -d"'" -f2 packt das Zeug in den einfachen Anführungszeichen
  6. Ergebnis ist: myApp
Zamnüsse
quelle
0

Ich würde verwenden , pgrepanstatt pswie so:

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

Dadurch werden alle übereinstimmenden Prozesse zurückgegeben javaund diejenigen herausgefiltert, die nur die enthaltenen anzeigen -Dapp.name=. Das letzte Bit \w+zeigt den Programmnamen an, vorausgesetzt, er enthält keine Leerzeichen.

HINWEIS: Mit dem -PSchalter zum grepAuflisten können Sie Dinge mithilfe von PCRE - Perl-kompatiblen regulären Ausdrücken angeben . Nicht alle Versionen grepunterstützen es, aber die meisten tun dies in moderneren Linux-Versionen.

Wenn Sie die gesamte Schlüssel- / Wertausgabe wünschen, ändern Sie folgende Dinge:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
slm
quelle