Nushell:將列表轉換為表格
有沒有一種慣用的方法可以將類似記錄的列表轉換為 Nushell 中的表?
我正在使用Stack Exchange API並獲取以下結果:
let questions = ('[ { "tags": [ "nushell" ], "title": "Nushell: Convert list to table" }, { "tags": [ "ssh", "tar" ], "title": "tar through ssh session", "closed_reason": "Duplicate" } ]' | from json)
請注意,
closed_reason
只有已關閉的問題才會返回,當然。這是有道理的——對於大多數問題,API 無需浪費頻寬返回空欄位。但這樣一來,
$questions
就變成了list<any>
Nushell中的一個。這意味著像這樣的操作:> $questions | group-by closed_reason
…導致(邏輯上)
cannot find column
錯誤。所有結果都需要具有相同的結構才能正常工作。例如,如果所有結果都有
closed_reason
’,像這樣:let questions = ('[ { "tags": [ "nushell" ], "title": "Nushell: Convert list to table", "closed_reason": "" }, { "tags": [ "ssh", "tar" ], "title": "tar through ssh session", "closed_reason": "Duplicate" } ]' | from json)
然後
$questions | describe
變成:table<tags: list<string>, title: string, closed_reason: string>
並且
$questions | group-by closed_reason
會工作。有沒有辦法將列表轉換/“規範化”為表格?
我已經嘗試過(使用原始
list<any>
結果):> $questions | table | group-by closed_reason # obviously doesn't work, since the table command is just for rendering # but worth a shot > $questions | to csv | from csv | group-by closed_reason # works, but loses the tag lists > $questions | transpose | transpose | headers | reject column0 | to json # Almost works, but still results in a list<any> # since the first question's closed_reason becomes null > $questions | transpose | transpose | headers | reject column0 | group-by closed_reason # results in "can't convert nothing to string"
終於找到了答案。
help --find def
當我發現適當命名的(但未在 Nushell Book 中引用)命令時,我碰巧正在尋找與 完全不同的東西default
,該命令本質上是 Nushell 內置的,用於執行@Kusalananda 推薦的相同操作jq
。因此,問題中的範例可以通過以下方式修復:
> $questions | default "" closed_reason | group-by closed_reason ╭───────────┬───────────────╮ │ │ [table 1 row] │ │ Duplicate │ [table 1 row] │ ╰───────────┴───────────────╯
結果是一個真正的 Nushell 表對象:
> $questions | default "" closed_reason | describe table<tags: list<string>, title: string, closed_reason: string>
有了這些,我就可以開始對 Stack API 進行一些切片和切塊了:
> $questions | default "" closed_reason | where closed_reason == "Duplicate" | update tags { $in.tags | str collect ','} ╭───┬─────────┬─────────────────────────┬───────────────╮ │ # │ tags │ title │ closed_reason │ ├───┼─────────┼─────────────────────────┼───────────────┤ │ 0 │ ssh,tar │ tar through ssh session │ Duplicate │ ╰───┴─────────┴─────────────────────────┴───────────────╯
nu
不幸的是,我對外殼不熟悉。不過,您絕對可以將數據作為 JSON 傳遞給jq
,添加帶有空字元串值的缺失鍵,然後將其轉換回 shell 的內部表示。在這裡,我正在更新
questions
變數,但您可以將jq
命令標記到原始let
命令上,而不是不必要地來迴轉換數據。let questions = ($questions | to json | jq '.[].closed_reason += ""' | from json)
然後您可以按以下方式對其進行分組
closed_reason
:〉$questions | group-by closed_reason ╭───────────┬───────────────╮ │ │ [table 1 row] │ │ Duplicate │ [table 1 row] │ ╰───────────┴───────────────╯