com awk
:
ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'
Estou tentando extrair o nome do aplicativo do comando ps
da seguinte forma:
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 egrep
, mas parece que não está funcionando:
ps -af -u sas|grep "java"| grep -v "grep"| egrep -o "-Dapp.name"
Como posso obter apenas o valor -Dapp.name
"myApp"?
Você não está mostrando a mensagem de erro que está recebendo, mas provavelmente
grep: unknown devices method
Isso porque, como todos ou pelo menos a maioria dos outros programas de linha de comando, grep
assume que qualquer coisa que comece com -
é uma opção e tenta analisá-lo como tal. Nesse caso, -D
é usado para instruir grep
sobre como lidar com um arquivo de dispositivo (consulte man grep
para obter detalhes). Uma maneira de contornar isso é usar --
, que diz grep
que qualquer coisa seguinte não é um sinalizador de opção.
Combinando isso com o recurso PCRE do GNU grep
, você pode fazer:
ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'
A expressão regular procura por -
e descarta-a ( \K
), depois a string Dapp.name=
seguida por tantos caracteres não espaciais quanto possível. A saída é:
Dapp.name=myApp
Se você quiser que a parte myApp
seja salva em uma variável, eu procuraria por ela sozinha:
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 grep
a saída de ps
para esse tipo de coisa, é isso que pgrep
é para:
app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*//p'
Mais complicado que as outras respostas, mas isso usa getopt
para lidar com a análise para você. Ainda outra alternativa.
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 ' '
"aperta" vários espaços em um único espaço em preparação para cut
cut -d' ' -f8-
divide a linha por espaços e pega todos os campos depois de 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
getopts -aql 'Dapp.name:' $(...)
analisa as opções de comando e gera apenas o nome longo que corresponde a Dapp.name
que tem um valor (denotado por :
), o resultado é --Dapp.name 'myApp' --
cut -d"'" -f2
pega o material nas citações simples myApp
Toda vez que você usa ps … | grep …
e precisa excluir o grep dos resultados, está fazendo errado.
A regra zero de analisar a saída de ps
é usar ferramentas mais confiáveis, como pgrep
, se disponível. Se você tiver pgrep, pgrep -f java
listará todos os processos executando o comando java
. A opção -l
adiciona a linha de comando para cada processo.
Para extrair o argumento para -Dapp.name
, você pode usar sed. Combine toda a linha, organize a parte interessante em um grupo e imprima esse grupo.
pgrep -lf java | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$//p'
A primeira regra de análise da saída de ps
é usar a opção -o
para selecionar os campos que você precisa. Aqui, você está interessado apenas nos argumentos do comando, então imprima apenas isso.
ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$//p'
Eu usaria pgrep
em vez de ps
da seguinte forma:
$ pgrep -fa java | grep -op "(<=-Dapp.name=)\w+"
Isso retornará todos os processos que correspondem a java
e, em seguida, filtrará os que mostrarem apenas os que contiverem -Dapp.name=
. O último bit, \w+
mostrará o nome do programa, assumindo que não contém espaços.
OBSERVAÇÃO: A opção -P
para grep
inscreve a capacidade de especificar coisas usando PCRE - Compatível com Perl Regular Expressões . Nem todas as versões do grep
suportam, mas a maioria inclui versões mais modernas do Linux.
Se você quiser a saída de chave / valor inteira, altere as coisas da seguinte forma:
$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"