0

I'm executing a bash script, and need to grab a specific value in a certain line. There can be multiple of these lines per se, although they are in different categories. Here is a sample output:

ffmpeg version N-92906-g54109b1d14 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 8.2.1 (GCC) 20181201 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt libavutil 56. 25.100 / 56. 25.100 libavcodec 58. 43.100 / 58. 43.100 libavformat 58. 25.100 / 58. 25.100 libavdevice 58. 6.101 / 58. 6.101 libavfilter 7. 46.101 / 7. 46.101 libswscale 5. 4.100 / 5. 4.100 libswresample 3. 4.100 / 3. 4.100 libpostproc 55. 4.100 / 55. 4.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\6 channel.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 creation_time : 2019-01-31T00:03:03.000000Z Duration: 00:00:30.12, start: 0.000000, bitrate: 2527 kb/s Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 960x540 [SAR 1:1 DAR 16:9], 2128 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : VideoHandler timecode : 00:00:00:00 Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 98 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : SoundHandler Stream #0:2: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 98 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : SoundHandler Stream #0:3: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 98 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : SoundHandler Stream #0:4: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 98 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : SoundHandler Stream #0:5: Data: none (tmcd / 0x64636D74), 0 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : TimecodeMediaHandler timecode : 00:00:00:00 Stream mapping: Stream #0:2 -> #0:0 (aac (native) -> pcm_s16le (native)) Press [q] to stop, [?] for help Output #0, null, to 'pipe:': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf58.25.100 Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default) Metadata: creation_time : 2019-01-31T00:03:03.000000Z handler_name : SoundHandler encoder : Lavc58.43.100 pcm_s16le size=N/A time=00:00:30.06 bitrate=N/A speed= 362x video:0kB audio:5180kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown [Parsed_astats_0 @ 000001e515c90f00] Channel: 1 [Parsed_astats_0 @ 000001e515c90f00] DC offset: 0.000098 [Parsed_astats_0 @ 000001e515c90f00] Min level: -0.394529 [Parsed_astats_0 @ 000001e515c90f00] Max level: 0.380586 [Parsed_astats_0 @ 000001e515c90f00] Min difference: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Max difference: 0.232958 [Parsed_astats_0 @ 000001e515c90f00] Mean difference: 0.005622 [Parsed_astats_0 @ 000001e515c90f00] RMS difference: 0.010923 [Parsed_astats_0 @ 000001e515c90f00] Peak level dB: -8.078412 [Parsed_astats_0 @ 000001e515c90f00] RMS level dB: -26.826611 [Parsed_astats_0 @ 000001e515c90f00] RMS peak dB: -16.475342 [Parsed_astats_0 @ 000001e515c90f00] RMS trough dB: -85.439368 [Parsed_astats_0 @ 000001e515c90f00] Crest factor: 8.657848 [Parsed_astats_0 @ 000001e515c90f00] Flat factor: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Peak count: 2 [Parsed_astats_0 @ 000001e515c90f00] Bit depth: 32/32 [Parsed_astats_0 @ 000001e515c90f00] Dynamic range: 215.482282 [Parsed_astats_0 @ 000001e515c90f00] Zero crossings: 109765 [Parsed_astats_0 @ 000001e515c90f00] Zero crossings rate: 0.082774 [Parsed_astats_0 @ 000001e515c90f00] Channel: 2 [Parsed_astats_0 @ 000001e515c90f00] DC offset: -0.000000 [Parsed_astats_0 @ 000001e515c90f00] Min level: -0.000010 [Parsed_astats_0 @ 000001e515c90f00] Max level: 0.000010 [Parsed_astats_0 @ 000001e515c90f00] Min difference: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Max difference: 0.000016 [Parsed_astats_0 @ 000001e515c90f00] Mean difference: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] RMS difference: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Peak level dB: -100.304024 [Parsed_astats_0 @ 000001e515c90f00] RMS level dB: -136.845747 [Parsed_astats_0 @ 000001e515c90f00] RMS peak dB: -115.764979 [Parsed_astats_0 @ 000001e515c90f00] RMS trough dB: -1134.435605 [Parsed_astats_0 @ 000001e515c90f00] Crest factor: 67.156208 [Parsed_astats_0 @ 000001e515c90f00] Flat factor: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Peak count: 2 [Parsed_astats_0 @ 000001e515c90f00] Bit depth: 32/32 [Parsed_astats_0 @ 000001e515c90f00] Dynamic range: 130.387729 [Parsed_astats_0 @ 000001e515c90f00] Zero crossings: 7128 [Parsed_astats_0 @ 000001e515c90f00] Zero crossings rate: 0.005375 [Parsed_astats_0 @ 000001e515c90f00] Overall [Parsed_astats_0 @ 000001e515c90f00] DC offset: 0.000098 [Parsed_astats_0 @ 000001e515c90f00] Min level: -0.394529 [Parsed_astats_0 @ 000001e515c90f00] Max level: 0.380586 [Parsed_astats_0 @ 000001e515c90f00] Min difference: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Max difference: 0.232958 [Parsed_astats_0 @ 000001e515c90f00] Mean difference: 0.002811 [Parsed_astats_0 @ 000001e515c90f00] RMS difference: 0.007724 [Parsed_astats_0 @ 000001e515c90f00] Peak level dB: -8.078412 [Parsed_astats_0 @ 000001e515c90f00] RMS level dB: -29.836911 [Parsed_astats_0 @ 000001e515c90f00] RMS peak dB: -16.475342 [Parsed_astats_0 @ 000001e515c90f00] RMS trough dB: -1134.435605 [Parsed_astats_0 @ 000001e515c90f00] Flat factor: 0.000000 [Parsed_astats_0 @ 000001e515c90f00] Peak count: 2.000000 [Parsed_astats_0 @ 000001e515c90f00] Bit depth: 32/32 [Parsed_astats_0 @ 000001e515c90f00] Number of samples: 1326080 

I'm thinking to pipe the whole output, get all possible matches, and grab only the last one (corresponding to overall category) and get `RMS level dB: -29.836911 (ignore the first part of line which is ffmpeg version I guess).

How can I get the last line of a match with grep? Or if you know other ways (e.g. sed or awk, that's fine too!)

1

2 Answers 2

2
tac file | grep -m 1 <args> 

or

ffmpeg <args> | tac | grep -m 1 <args> 

to read piped input.

That would be significantly faster than your currently accepted answer of grep | tail. For example:

$ seq 100000000 > file $ time grep '3' file | tail -1 99999993 real 0m6.781s user 0m7.500s sys 0m1.435s $ time tac file | grep -m 1 3 99999993 real 0m0.046s user 0m0.015s sys 0m0.015s 
Sign up to request clarification or add additional context in comments.

2 Comments

Tnx! Will check it out! What is that file? Can you add my ffmepg command to it and have a full answer?
file contains the sample input shown in your question. If the input comes directly from a command named cmd instead of a file named file then just use cmd | tac | grep instead of tac file | grep.
2

Pipe the output from grep to tail -1 to get only the last match:

grep <args> | tail -1 

5 Comments

I'm having some issues with grep. Why this doesn't work showing only RMS lines?! ffmpeg -i 540p.mp4 -map 0:a:1 -af astats -f null - | grep -i RMS
ok, got it. Needed to add some extra stuff: ffmpeg -i 540p.mp4 -map 0:a:1 -af astats -f null - 2>&1 | grep 'RMS level dB' | tail -1
That would be a very slow approach since grep will do a regexp comparison on every line of input, print potentially many lines of output, and then tail will throw all of that effort away except for the last line of output!
Given the use case I don't think performance will be an issue. Maybe if grepping a multi gigabyte file...
That may be but we're not answering just for the use case presented in the question but also for the next person who searches the archives for an answer to their own Get the line of last grep match in bash problem and does need an efficient approach so it's worth stating.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.