Come estrarre una coppia chiave-valore dal comando ps


10

Sto cercando di estrarre il nome dell'applicazione dal pscomando in questo modo:

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

e produce quanto segue:

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

Ho provato a usare egrepma non sembra funzionare:

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

Come posso ottenere solo il -Dapp.namevalore "myApp"?


se il grepmodello inizia con -, è necessario inserirlo dopo l' -eopzione. Altrimenti, verrà trattata come un'opzione. Ma questo corrisponderà solo alla parola -Dapp.name, non alla parte successiva.
Barmar,

alternativamente:grep -o -- -Dapp.name
strugee,

puoi usare grep [j]avaper evitare il comando grep -v "grep"(testato su bash)
HVNSweeting

Risposte:



8

Non stai mostrando il messaggio di errore che stai ricevendo ma è probabilmente

grep: metodo di dispositivi sconosciuti

Questo perché, come tutti o almeno la maggior parte degli altri programmi da riga di comando, greppresuppone che tutto ciò che inizia con a -sia un'opzione e cerchi di analizzarlo come tale. In questo caso, -Dviene utilizzato per istruire grepsu come gestire un file del dispositivo (vedere man grepper i dettagli). Un modo per aggirare questo è usare --che dice grepche tutto ciò che segue non è un flag di opzione.

Combinandolo con la capacità PCRE di GNU grep, puoi fare:

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

L'espressione regolare cerca a -e la scarta ( \K), quindi la stringa Dapp.name=seguita dal maggior numero possibile di caratteri non spaziali. L'output è:

Dapp.name=myApp

Se si desidera myAppsalvare la parte in una variabile, la cerco da sola:

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

Per assegnarlo a una variabile:

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

Tuttavia, non dovresti mai grepottenere psquesto tipo di cose, ecco a cosa pgrepservono:

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

Ogni volta che usi ps … | grep …e devi escludere grep dai risultati, stai sbagliando.

La regola zeroth di analizzare l'output di psè utilizzare strumenti più affidabili come pgrepse disponibili. Se hai pgrep, pgrep -f javaelenca tutti i processi che eseguono il comando java. L'opzione -laggiunge la riga di comando per ogni processo.

Per estrarre l'argomento -Dapp.name, puoi usare sed. Abbina l'intera riga, organizza il riempimento della parte interessante in un gruppo e stampa quel gruppo.

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

La prima regola per analizzare l'output di psè utilizzare l'opzione -oper selezionare i campi di cui hai bisogno. Qui, sei interessato solo agli argomenti del comando, quindi stampa solo quello.

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

3

Più complicato delle altre risposte, ma questo serve getopta gestire l'analisi per te. Ancora un'altra alternativa.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. il tuo comando: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "stringe" più spazi in un unico spazio in preparazione per cut
  3. cut -d' ' -f8- divide la linea per spazi e afferra tutti i campi dopo 8 inclusi, il risultato è /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:' $(...)analizza le opzioni di comando e restituisce solo il nome lungo che corrisponde a Dapp.namechi ha un valore (indicato da :), il risultato è--Dapp.name 'myApp' --
  5. cut -d"'" -f2 prende le cose tra virgolette singole
  6. Il risultato è: myApp

0

Vorrei usare pgrepinvece di pscosì:

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

Ciò restituirà tutti i processi corrispondenti javae quindi filtrerà quelli che mostrano solo quelli che contengono -Dapp.name=. L'ultimo bit \w+mostrerà il nome del programma, supponendo che non contenga spazi.

NOTA: l' -Pinterruttore per grepaumentare la capacità di specificare le cose usando PCRE - Perl Regular Regular Expressions . Non tutte le versioni greplo supportano, ma la maggior parte è inclusa nelle versioni più moderne di Linux.

Se vuoi l'intero output chiave / valore, cambia le cose in questo modo:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.