Intereting Posts
Почему программы работают с sudo, не имеют системной темы? Каковы преимущества работы pvcreate в разделе, а не на устройстве? Как установить b43-прошивку на арку без доступа в Интернет? Группа фиксации в сопоставлениях протокола xmodmap / core (XChangeKeyboardMapping ()) Является ли какое-либо решение для создания интерактивного TCP / UDP-сервера под Linux? Как выбрать главы учебных пособий в Uemacs Как началась функция ~ / .local / bin? Насколько распространено это? возможно ли создать файл с учетом хеша md5 Debian 8 Jessie, паника ядра при выключении Отформатируйте USB-накопитель как непривилегированный пользователь несколько файлов переименовать – шаблоны имен файлов Служба Daemon, которая выполняет последовательность процессов (сбалансированное распределение) Как настроить отдельную среду bash с помощью только утилит GNU на OS X? Включить шифрование 3DES для openssl 1.0.1t на Debian 7 Проблема выполнения тестов HPCC и IMB на платформе IBM HPC

Как преобразовать вывод ps (1) в JSON?

Я хочу преобразовать вывод команды ps в JSON, чтобы обрабатывать ее как структурированные данные (с jq в данном конкретном случае). Как мне это сделать?

Результат выглядит следующим образом:

  PID TTY TIME CMD 20162 pts/2 00:00:00 ps 28280 pts/2 00:00:02 zsh 

Строка заголовка всегда присутствует.

Существует два очевидных способа представления вывода столбцов в JSON: как массив массивов и как массив объектов. В первом случае вы конвертируете каждую строку ввода в массив; в последнем, к объекту.

Команды, перечисленные ниже, работают как минимум с выходом procps-ng на Linux для команд ps и ps -l .

Вариант №1: массив массивов

Использование Perl

Вы можете преобразовать выходные данные с помощью Perl и модуля CPAN JSON :: XS .

 # ps | perl -MJSON -lane 'my @a = @F; push @data, \@a; END { print encode_json \@data }' [["PID","TTY","TIME","CMD"],["12921","pts/2","00:00:00","ps"],["12922","pts/2","00:00:00","perl"],["28280","pts/2","00:00:01","zsh"]] 

Используя jq

Кроме того, вы можете использовать jq для выполнения преобразования.

 # ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]' [ [ "PID", "TTY", "TIME", "CMD" ], [ "16694", "pts/2", "00:00:00", "ps" ], [ "16695", "pts/2", "00:00:00", "jq" ], [ "28280", "pts/2", "00:00:02", "zsh" ] ] 

Вариант № 2: массив объектов

Вы можете преобразовать вход в массив объектов JSON со значимо названными ключами, взяв имена ключей из строки заголовка.

Это требует немного больших усилий и, в частности, немного сложнее в jq. Тем не менее, результат, вероятно, более удобочитаемый для человека.

Использование Perl

 # ps | perl -MJSON -lane 'if (!@keys) { @keys = @F } else { my %h = map {($keys[$_], $F[$_])} 0..$#keys; push @data, \%h } END { print encode_json \@data }' [{"TTY":"pts/2","CMD":"ps","TIME":"00:00:00","PID":"11030"},{"CMD":"perl","TIME":"00:00:00","PID":"11031","TTY":"pts/2"},{"TTY":"pts/2","CMD":"zsh","TIME":"00:00:01","PID":"28280"}] 

Обратите внимание, что ключи в произвольном порядке для каждой записи. Это артефакт о том, как работают хэши Perl.

Используя jq

 # ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]] | .[0] as $header | .[1:] | [.[] | [. as $x | range($header | length) | {"key": $header[.], "value": $x[.]}] | from_entries]' [ { "PID": "19978", "TTY": "pts/2", "TIME": "00:00:00", "CMD": "ps" }, { "PID": "19979", "TTY": "pts/2", "TIME": "00:00:00", "CMD": "jq" }, { "PID": "28280", "TTY": "pts/2", "TIME": "00:00:02", "CMD": "zsh" } ] 

Я бы предложил явно установить, что вы хотите, чтобы вывод ps был с опцией -o. Кроме того, используйте –no-header, если вы не хотите, чтобы заголовок в вашем json-выходе.

Я бы предложил в качестве отправной точки – не использовать ps а затем разобрать его. Это хороший способ причинить себе боль (например, вы хотите расширить его, чтобы включить аргументы командной строки, которые ограничены пробелами).

Таким простым было бы:

 #!/usr/bin/env perl use strict; use warnings; use JSON; use Proc::ProcessTable; my $json; foreach my $proc ( @{ Proc::ProcessTable -> new -> table } ) { push ( @$json, { %$proc } ); } print to_json ( $json, { pretty => 1 } ); 

Это даст вам полный список полей ps , которые могут быть излишними.

И если вы хотите сделать это одним лайнером:

 perl -MJSON -MProc::ProcessTable -e 'print to_json ( [ map { %$_ } } @{ Proc::ProcessTable->new->table } ], { pretty => 1 } );'