Jak wyodrębnić parę klucz-wartość z polecenia ps

10

Próbuję wyodrębnić nazwę aplikacji z pspolecenia w następujący sposób:

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

i produkuje:

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

Próbowałem użyć, egrepale wydaje się, że nie działa:

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

Jak mogę uzyskać tylko -Dapp.namewartość „myApp”?

Sas
źródło
jeśli grepwzór zaczyna się od -, musisz umieścić go po -eopcji. W przeciwnym razie będzie to traktowane jako opcja. Ale to po prostu pasuje do słowa -Dapp.name, a nie do części po nim.
Barmar
na przemian:grep -o -- -Dapp.name
strugee
możesz użyć, grep [j]avaaby uniknąć polecenia grep -v "grep"(testowane na bash)
HVNSweeting

Odpowiedzi:

7

Z awk:

ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'
jasonwryan
źródło
8

Nie wyświetla się wyświetlany komunikat o błędzie, ale prawdopodobnie jest to możliwe

grep: metoda nieznanych urządzeń

Dzieje się tak, ponieważ, podobnie jak wszystkie inne programy wiersza poleceń, grepzakłada, że ​​wszystko, co zaczyna się na a, -jest opcją i próbuje je parsować jako takie. W takim przypadku -Dsłuży do instruowania, grepjak postępować z plikiem urządzenia (zobacz man grepszczegóły). Jednym ze sposobów obejścia tego jest użycie, --które mówi, grepże cokolwiek następuje nie jest flagą opcji.

Łącząc to z funkcją GNU PCRE grep, możesz:

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

Wyrażenie regularne szuka a -i odrzuca je ( \K), a następnie ciąg znaków, Dapp.name=po którym następuje jak najwięcej znaków spacji, jak to możliwe. Dane wyjściowe to:

Dapp.name=myApp

Jeśli chcesz myAppzapisać część w zmiennej, szukałbym tego sam:

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

Aby przypisać ją do zmiennej:

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

Jednak nigdy nie powinieneś uzyskiwać greprezultatów psdla tego rodzaju rzeczy, właśnie po to pgrep:

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

Za każdym razem, gdy używasz ps … | grep …i chcesz wykluczyć grep z wyników, robisz to źle.

Zerową zasadą parsowania wyniku psjest użycie bardziej niezawodnych narzędzi, takich jak pgrepdostępne. Jeśli masz pgrep, pgrep -f javawyświetla listę wszystkich procesów uruchamiających polecenie java. Opcja -ldodaje wiersz poleceń dla każdego procesu.

Aby wyodrębnić argument -Dapp.name, możesz użyć sed. Dopasuj całą linię, umieść ciekawą część w grupie i wydrukuj tę grupę.

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

Pierwszą zasadą analizowania danych wyjściowych psjest użycie opcji -odo wybrania potrzebnych pól. Tutaj interesują Cię tylko argumenty poleceń, więc wypisz tylko to.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'
Gilles „SO- przestań być zły”
źródło
3

Bardziej skomplikowane niż inne odpowiedzi, ale służy to getoptdo obsługi analizy. Jeszcze jedna alternatywa.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. twoje polecenie: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' „ściska” wiele spacji w jedną przestrzeń w ramach przygotowań cut
  3. cut -d' ' -f8- dzieli linię przez spacje i pobiera wszystkie pola po 8 włącznie, wynikiem jest /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:' $(...)analizuje opcje polecenia i zwraca tylko Dapp.namedługą nazwę, która pasuje do tego, kto ma wartość (oznaczoną przez :), wynikiem jest--Dapp.name 'myApp' --
  5. cut -d"'" -f2 chwyta rzeczy w pojedyncze cytaty
  6. Wynik to: myApp
zamnuts
źródło
0

Chciałbym użyć pgrepzamiast pstak:

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

Spowoduje to zwrócenie wszystkich pasujących procesów, javaa następnie odfiltruje te, pokazując tylko te, które zawierają -Dapp.name=. Ostatni bit \w+pokaże nazwę programu, zakładając, że nie zawiera spacji.

UWAGA:-P przełącznik grepwerbuje zdolność do określenia rzeczy za pomocą PCRE - pcre . Nie wszystkie wersje grepgo obsługują, ale większość z nich jest dołączana do bardziej nowoczesnych wersji Linuksa.

Jeśli chcesz otrzymać cały wynik klucz / wartość, zmień takie rzeczy:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
slm
źródło