Como extrair um par de valores-chave do comando ps


10

Estou tentando extrair o nome do aplicativo do pscomando como este:

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

e produz o seguinte:

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

Eu tentei usar, egrepmas não parece estar funcionando:

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

Como posso obter apenas o -Dapp.namevalor "myApp"?


se o greppadrão começar -, você precisará colocá-lo após a -eopção. Caso contrário, será tratado como uma opção. Mas isso apenas corresponderá à palavra -Dapp.name, não à parte posterior.
Barmar 15/10

alternadamente:grep -o -- -Dapp.name
strugee 15/10

você pode usar grep [j]avapara evitar o comando grep -v "grep"(testado no bash) #
2144 HVNSweeting

Respostas:



8

Você não está mostrando a mensagem de erro que está recebendo, mas provavelmente é

grep: método de dispositivos desconhecidos

Isso ocorre porque, como todos ou pelo menos a maioria dos outros programas de linha de comando, grepassume que qualquer coisa que comece com a -é uma opção e tenta analisá-la como tal. Nesse caso, -Dé usado para instruir grepsobre como lidar com um arquivo de dispositivo (consulte man greppara obter detalhes). Uma maneira de contornar isso é usar o --que informa grepque qualquer coisa a seguir não é um sinalizador de opção.

Combinando isso com a capacidade PCRE do GNU grep, você pode:

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

A expressão regular procura por -e a descarta ( \K), depois a sequência Dapp.name=seguida pelo maior número possível de caracteres não espaciais. A saída é:

Dapp.name=myApp

Se você deseja que a myApppeça seja salva em uma variável, eu procuraria apenas isso:

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

Para atribuí-lo a uma variável:

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

No entanto, você nunca deve grepproduzir psesse tipo de coisa, pgrepé para isso:

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

Sempre que você usar ps … | grep …e precisar excluir o grep dos resultados, estará fazendo errado.

A regra zero de analisar a saída de psé usar ferramentas mais confiáveis, como pgrepse disponíveis. Se você possui o pgrep, pgrep -f javalista todos os processos que executam o comando java. A opção -ladiciona a linha de comando para cada processo.

Para extrair o argumento -Dapp.name, você pode usar sed. Combine a linha inteira, organize a parte interessante de um grupo e imprima esse grupo.

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

A primeira regra de analisar a saída de psé usar a opção -opara selecionar os campos que você precisa. Aqui, você está interessado apenas nos argumentos do comando, portanto, imprima apenas isso.

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

3

Mais complicado do que as outras respostas, mas isso serve getoptpara lidar com a análise para você. Mais uma alternativa.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. seu comando: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "espreme" vários espaços em um único espaço em preparação para cut
  3. cut -d' ' -f8- divide a linha por espaços e agarra todos os campos após 8 inclusive, o resultado é /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:' $(...)analisa as opções de comando e gera apenas o nome longo que corresponde a Dapp.namequem possui um valor (indicado por :), o resultado é--Dapp.name 'myApp' --
  5. cut -d"'" -f2 pega o material entre aspas simples
  6. O resultado é: myApp

0

Eu usaria em pgrepvez de psassim:

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

Isso retornará todos os processos correspondentes javae depois os filtrará, mostrando apenas os que contêm -Dapp.name=. O último bit \w+mostrará o nome do programa, assumindo que ele não contém espaços.

NOTA: A -Popção para grepsolicita a especificação de itens usando Expressões regulares compatíveis com PCRE - Perl . Nem todas as versões de grepsuporte, mas a maioria inclui as versões mais modernas do Linux.

Se você deseja a saída completa da chave / valor, mude da seguinte maneira:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.