
為了標準化我的影片庫,我正在嘗試找到一種方法來快速建立需要轉換的檔案清單。看完之後這問題及其答案(以及大量谷歌搜尋)我認為我已經弄清楚了基礎知識,但我在詳細說明 jq 部分時遇到了困難。作為參考,我開始使用的 jq 指令如下:
jq -c '.format.filename as $path |
.streams[]? |
select(.codec_type=="video" and .codec_name!="h264") |
.codec_name as $vcodec |
{video: $vcodec, path: $path}'
並且,為了簡單起見,我們假設這就是提供給 jq 的內容:
{
"streams": [
{
"index": 0,
"codec_name": "hevc",
"codec_type": "video"
},
{
"index": 1,
"codec_name": "aac",
"codec_type": "audio"
}
],
"format": {
"filename": "Video.mkv"
}
}
產生以下輸出:
{"video":"hevc","path":"./Video.mkv"}
這很棒,但我想更進一步 - 我還想包括用於任何音訊串流的編解碼器。因此,給定相同的輸入,我想要以下輸出:
{"video":"hevc","audio":"aac","path":"./Video.mkv"}
我該如何實現這個目標?
答案1
若要選擇音訊和視訊編解碼器類型並排除h264
視訊:
$ jq '.format.filename as $path |
[.streams[]? | select(.codec_type=="audio"
or (.codec_type=="video"
and .codec_name!="h264")) |
{(.codec_type): .codec_name, $path}] |
group_by(.path) | map(add) | .[]' input.json
$ jq --version
jq-1.5-1-a5b5cbe
如果 shell 命令變得複雜並且需要超過幾行;我改用更詳細的 Python 來管理複雜性:
result = dict(path=data['format']['filename'])
for stream in data['streams']:
if (stream['codec_type'] == 'audio'
or (stream['codec_type'] == 'video'
and stream['codec_name'] != 'h264')):
result[stream['codec_type']] = stream['codec_name'] # last value wins
data
是輸入(data = json.loads(json_text)
),result
是期望的輸出(print(json.dumps(result))
)。
如果您更熟悉 Python 中的命令式程式設計而不是jq
.
答案2
這是另一種方法。
$ jq -M '
def getpath: {path: .format.filename} ;
def getcodecs: [
.streams[]?
| {(.codec_type):.codec_name}
| if . == {"video":"h264"} then empty else . end
] | add
;
getpath + getcodecs
' input.json
輸出
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}