mfaiz
mfaiz

Reputation: 535

Create a string from multiple tags in json file in jq

I am trying to get multiple values from keys inside json. I have managed the first part, but the second part is not giving me what I want.

Here is a snippet of some data in json of a video:

{
"streams": [
    {
        "index": 0,
        "codec_name": "h264",
        "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
        "profile": "Main",
        "codec_type": "video",
        "codec_time_base": "0/2",
        "codec_tag_string": "[27][0][0][0]",
        "codec_tag": "0x001b",
        "width": 1920,
        "height": 1080,
        "coded_width": 1920,
        "coded_height": 1088,
        "has_b_frames": 1,
        "sample_aspect_ratio": "1:1",
        "display_aspect_ratio": "16:9",
        "pix_fmt": "yuv420p",
        "level": 40,
        "chroma_location": "left",
        "field_order": "progressive",
        "refs": 1,
        "is_avc": "false",
        "nal_length_size": "0",
        "id": "0x100",
        "r_frame_rate": "25/1",
        "avg_frame_rate": "0/0",
        "time_base": "1/90000",
        "start_pts": 1397779146,
        "start_time": "15530.879400",
        "bits_per_raw_sample": "8",
        "disposition": {
            "default": 0,
            "dub": 0,
            "original": 0,
            "comment": 0,
            "lyrics": 0,
            "karaoke": 0,
            "forced": 0,
            "hearing_impaired": 0,
            "visual_impaired": 0,
            "clean_effects": 0,
            "attached_pic": 0,
            "timed_thumbnails": 0
        }
    },
    {
        "index": 1,
        "codec_name": "aac",
        "codec_long_name": "AAC (Advanced Audio Coding)",
        "codec_type": "audio",
        "codec_time_base": "1/0",
        "codec_tag_string": "[15][0][0][0]",
        "codec_tag": "0x000f",
        "sample_fmt": "fltp",
        "sample_rate": "0",
        "channels": 0,
        "bits_per_sample": 0,
        "id": "0x101",
        "r_frame_rate": "0/0",
        "avg_frame_rate": "0/0",
        "time_base": "1/90000",
        "disposition": {
            "default": 0,
            "dub": 0,
            "original": 0,
            "comment": 0,
            "lyrics": 0,
            "karaoke": 0,
            "forced": 0,
            "hearing_impaired": 0,
            "visual_impaired": 0,
            "clean_effects": 0,
            "attached_pic": 0,
            "timed_thumbnails": 0
        },
        "tags": {
            "language": "eng"
        }
    },
    {
        "index": 2,
        "codec_name": "dvb_teletext",
        "codec_long_name": "DVB teletext",
        "codec_type": "subtitle",
        "codec_tag_string": "[6][0][0][0]",
        "codec_tag": "0x0006",
        "id": "0x102",
        "r_frame_rate": "0/0",
        "avg_frame_rate": "0/0",
        "time_base": "1/90000",
        "disposition": {
            "default": 0,
            "dub": 0,
            "original": 0,
            "comment": 0,
            "lyrics": 0,
            "karaoke": 0,
            "forced": 0,
            "hearing_impaired": 0,
            "visual_impaired": 0,
            "clean_effects": 0,
            "attached_pic": 0,
            "timed_thumbnails": 0
        },
        "tags": {
            "language": "eng"
        }
    }
] 
}

So I want to get the video information first followed by audio information:

Expected result:

"1080,h264,aac"

Here is the code I am trying, which gives me a blank output:

.streams[] | "\(select(.codec_type=="video") | "\(.height),\(.codec_name)"),\(select(.codec_type=="audio") | "\(.codec_name)")"

However, when referencing a single array, it works:

.streams[] | "\(select(.codec_type=="video") | "\(.height),\(.codec_name)"),"
"1080,h264,"

I want both audio and video information.

Jq Play

Upvotes: 1

Views: 440

Answers (2)

Dmitry
Dmitry

Reputation: 1293

as an alternative, one could use walk-path based unix utility jtc to select required records:

bash $ <video.json jtc -w'[codec_type]:<video>[-1][height]<H>v[-1][codec_name]<C>v[-2][codec_type]:<audio>[-1][codec_name]' -T'"{H},{C},{}"'
"1080,h264,aac"
bash $ 

PS> Disclosure: I'm the creator of the jtc - shell cli tool for JSON operations

Upvotes: 1

peak
peak

Reputation: 116750

The following seems to be what you want:

.streams
| (.[] | select(.codec_type == "video") | "\(.height),\(.codec_name),")
+ (.[] | select(.codec_type == "audio") | "\(.codec_name)") 

It does produce the desired output, and it does match the problem description and sample code, but if (for example) there are multiple video objects, or no audio object, the results may not be exactly what you want.

Upvotes: 1

Related Questions