computing
  • 3

Solved Batch File To Find The Last Occurrence Of a String?

  • 3

I’m trying to set a variable and write to a file the value of the last occurrence of ‘time=’, 00:24:53.16, in this example file.

——– file: input.txt ——–
Input #0, mp3, from ‘test.mp3’:
Metadata:
encoder : Lavf57.51.102
Duration: 00:23:41.31, start: 0.025057, bitrate: 128 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
Metadata:
encoder : Lavc57.60
Output #0, null, to ‘pipe:’:
Metadata:
encoder : Lavf57.51.102
Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Metadata:
encoder : Lavc57.60.101 pcm_s16le
Stream mapping:
Stream #0:0 -> #0:0 (mp3 (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
size=N/A time=00:03:29.65 bitrate=N/A speed= 419x
size=N/A time=00:07:56.65 bitrate=N/A speed= 477x
size=N/A time=00:12:25.43 bitrate=N/A speed= 497x
size=N/A time=00:16:56.45 bitrate=N/A speed= 508x
size=N/A time=00:21:22.56 bitrate=N/A speed= 513x
size=N/A time=00:24:53.16 bitrate=N/A speed= 515x
video:0kB audio:25720kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
——– end of file ————

The trouble I’m having comes from the fact that all the ‘lines’ starting with ‘size=’ (except the last one) end with <sp><sp><sp><sp><cr>, no <lf>, so they are really part of a single line as far a parse-ability is concerned. The last ‘size=’ line has a <cr><lf>.

So, the problem really boils down to extracting the last of several occurrences of a string in a line of unknown length, e.g.:

size=N/A time=00:03:29.65 bitrate=N/A speed= 419x size=N/A time=00:07:56.65 bitrate=N/A speed= 477x size=N/A time=00:12:25.43 bitrate=N/A speed= 497x size=N/A time=00:16:56.45 bitrate=N/A speed= 508x size=N/A time=00:21:22.56 bitrate=N/A speed= 513x size=N/A time=00:24:53.16 bitrate=N/A speed= 515x

In case it makes the solution any easier, the desired ‘time=’ value will always be the last one in the file, and will always be the ‘largest’.

The following batch file almost works, but it finds and processes the first ‘time=’ value, not the last. It converts the value to seconds, strips the echo-added <cr><lf>, sets an environment variable, and sends the result to a file. It works except on the wrong data. Is there some way to accomplish this in a pure Win batch file?

@echo off
for /F “tokens=1-7 delims==:. ” %%1 in (input.txt) do (if “%%1″==”size” call :findtime %%4 %%5 %%6 %%7)
:findtime
echo:
set /A s=%3 & set /A s=s+%2*60 & set /A s=s+%1*60*60
echo:%1:%2:%3.%4 = %s%.%4 seconds
set dur=%s%.%4
echo:%dur% = includes a CRLF
<nul (set/p z=%dur%)
echo: = stripped CRLF, method1
(echo:|set /p =”%dur%”)>duration.txt %= strip CRLF then send to file for later use =%
type duration.txt
echo: = stripped CRLF, method2
echo:
pause

Share

1 Answer

  1. ::====== script starts here ===============
    :: get last instance of time=nnnnn
    :: lasttime.bat 2016-12-04 15:44:02.71
    @echo off & setLocal enableDELAYedeXpansioN

    :main
    for /f “tokens=* delims= ” %%a in (‘find “time=” ^< input.txt’) do (
    set S=%%a
    )
    call :sub1 !S!
    echo V is set to !V!
    goto :eof

    :sub1
    for %%i in (%*) do (
    :loop1
    if %1 equ time set V=%1=%2
    if “%2” neq “” SHIFT && goto :loop1
    )
    goto :eof
    ::====== script ends here =================

    =====================

    M2 Get custom script or take private lessons

    • 0