Ps
如何將 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 中表示列數據輸出有兩種明顯的方式:作為數組數組和作為對像數組。在前一種情況下,您將輸入的每一行轉換為數組;在後者中,對一個對象。
下面列出的命令至少適用於 Linux 上 procps-ng 的輸出,用於命令
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" } ]