Estou usando jq 1.7
Dados
Estou operando em info.json baixado por yt-dlp
yt-dlp --write-info-json --skip-download https://www.youtube.com/watch?v=vlIO-7Rpi7c
JQ - Tarefa
- Agora quero remover todo array dentro das legendas cujo nome não é
de
,en-US
e dentrode
,en-US
selecionar todos os objetos com elementoext == vtt
.
Isso funciona com sucesso da seguinte maneira :
jq 'pick(.subtitles | .de[],."en-US"[] | select (.ext == "vtt")) | del(..|nulls)' *.json
saída
{
"subtitles": {
"de": [
{
"ext": "vtt",
"url": "https://www.youtube.com/api/timedtext?v=vlIO-7Rpi7c&ei=JS05ZoT2Ftf0i9oP8dy4mAo&caps=asr&opi=112496729&xoaf=5&hl=en&ip=0.0.0.0&ipbits=0&expire=1715048341&sparams=ip%2Cipbits%2Cexpire%2Cv%2Cei%2Ccaps%2Copi%2Cxoaf&signature=AB2ECEEABF48D1A16ADC7ACCB8A072D63EE12DCC.5F56904251766FB68624A68FF2BBB57B9CCFFD2F&key=yt8&lang=de&fmt=vtt",
"name": "German"
}
],
"en-US": [
{
"ext": "vtt",
"url": "https://www.youtube.com/api/timedtext?v=vlIO-7Rpi7c&ei=JS05ZoT2Ftf0i9oP8dy4mAo&caps=asr&opi=112496729&xoaf=5&hl=en&ip=0.0.0.0&ipbits=0&expire=1715048341&sparams=ip%2Cipbits%2Cexpire%2Cv%2Cei%2Ccaps%2Copi%2Cxoaf&signature=AB2ECEEABF48D1A16ADC7ACCB8A072D63EE12DCC.5F56904251766FB68624A68FF2BBB57B9CCFFD2F&key=yt8&lang=en-US&fmt=vtt",
"name": "English (United States)"
}
]
}
}
Emitir
Para alguns vídeos do Youtube, o arquivo json não contém "en-US", mas contém "en", enquanto alguns contêm todos os três de, en, en-US. Então eu escrevi o seguinte
jq 'pick(.subtitles | .de[],.en[],."en-US"[] | select (.ext == "vtt")) | del(..|nulls)' *.json
Erro
jq: erro (em: 69): Não é possível iterar sobre nulo (nulo)
É necessária ajuda
Como selecionar apenas .ext == "vtt" apenas para o idioma en,en-US,de se nem todos esses idiomas estiverem presentes no arquivo json?
Eu separaria o
pick()
e oselect()
para que os idiomas corretos sejam escolhidos primeiro:Em seguida, selecione apenas os elementos dos arrays que possuem o
ext
valor correto, ignorando quaisquernull
valores:Acima,
map_values()
aplicará a expressão fornecida ao valor de cada chave (e o valor de cada chave é um array). Com. // empty
, qualquer valor que seja logicamente falso , comonull
, é removido. A expressãomap(select())
removerá qualquer elemento da matriz que não atenda aos critérios de seleção.Junto:
Isso também funcionaria se o
subtitles
objeto estivesse vazio ou ausente.Para deixar as outras chaves de nível superior no lugar e modificar apenas o que está abaixo
subtitles
:Observe como isso é composto pelos mesmos componentes básicos da expressão acima, mas aqui modificamos
subtitles
no documento original enquanto anteriormente modificamossubtitles
no documento "escolhido" (um documento ondesubtitles
existiam apenas e algumas de suas chaves).