1

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

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I ended up saving the output as a variable and accessing it separately each time.
1

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

2 Comments

a jq alternative. Didn't even know one this comprehensive existed. Unfortunately the system I am on comes with a pre set tools and jq is one of them with no room to expand on it unless the developers implement it. I suppose it could be compiled for it.
yes, jtc is relatively new (was first published less than a year ago). jtc is written in very idiomatic a portable way, should be no problem compiling it on any system as long it has c++14 or higher version compiler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.