Как извлечь пару ключ-значение из команды ps

Как извлечь пару ключ-значение из команды ps

Я пытаюсь извлечь имя приложения из psкоманды следующим образом:

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

и это производит следующее:

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

Я пробовал использовать egrep, но, похоже, это не работает:

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

Как получить только -Dapp.nameзначение «myApp»?

решение1

Вы не показываете сообщение об ошибке, которое получаете, но, вероятно, оно

grep: неизвестный метод устройств

Это потому, что, как и все или, по крайней мере, большинство других программ командной строки, grepпредполагает, что все, что начинается с a, -является опцией, и пытается проанализировать это как таковую. В этом случае -Dиспользуется для указания grepтого, как работать с файлом устройства (см. man grepподробности). Один из способов обойти это — использовать which, --который сообщает grep, что все, что следует за этим, не является флагом опции.

Объединив это с возможностями PCRE в GNU grep, вы можете сделать:

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

Регулярное выражение ищет a -и отбрасывает его ( \K), затем строку, Dapp.name=за которой следует как можно больше непробельных символов. Вывод:

Dapp.name=myApp

Если вам нужна myAppчасть, сохраненная в переменной, я бы искал только ее:

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

Чтобы присвоить его переменной:

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

Однако, вы никогда не должны grepвыводить psдля такого рода вещей, вот чтоpgrepдля:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"

решение2

С awk:

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

решение3

ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'

решение4

Сложнее, чем другие ответы, но это используется getoptдля обработки разбора для вас. Еще одна альтернатива.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. Ваша команда:ps -af -u sas | grep java | grep -v grep
  2. tr -s ' '«сжимает» несколько пространств в одно пространство в рамках подготовки кcut
  3. cut -d' ' -f8-разбивает строку пробелами и захватывает все поля после 8 включительно, результат/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:' $(...)анализирует параметры команды и выводит только длинное имя, которое соответствует Dapp.nameзначению who (обозначается :), результат--Dapp.name 'myApp' --
  5. cut -d"'" -f2захватывает то, что в одинарных кавычках
  6. Результат:myApp

Связанный контент