windowsbatch-filecmdforfiles

Get a variable from filename string in windows batch


good day, i have a folder with 400 files and i want to print a "name" from the filenames this is the structure ej:

20201323223_vendo.perfil01_17872513294967257_1601950878_live.mp4
20201323223__vvcastrillon_12_17949951031375250_1601939874_live.mp4
2020323123_yessromero.g_17849208194340047_1601945592_live.mp4
2020323223_ziizii_08_17979840166310477_1601929868_live.mp4

and what i need is

vendo.perfil01
_vvcastrillon_12
yessromero.g
ziizii_08

Im try to loop in the files and separate whit the _ and extract the 2 and 3 token numeral conditioning but the result is wrong and missing variables

@echo off
setlocal EnableDelayedExpansion
:loop
SET max=5000
for /F "delims=" %%I in ('dir "*_*_*.mp4" /A-D /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V "\\outdir\\"') do (for /F "eol=| tokens=2,3 delims=_" %%J in ("%%~nI") do (SET "var="&for /f "delims=0123456789" %%a in ("%%K") do SET var=%%a
if defined var ( set nam=%%J_%%K ) else ( set nam=%%J )
)
echo/!nam!
)
timeout 10 > nul
goto loop

i think the answer is remove the first number before the _ then the string _xxxxxx_xxxxxxx_live.mp4 at the end but i dont know how read in reverse the tokens

tanks for any help


Solution

  • Since you have got different numbers of _-separated items in your file names and even adjacent _, so using for /F to split them into specific tokens with delims=_ is not the best choice.

    I would use a standard for-loop instead, which receives modified file names, namely with each _ replaced by " " and enclosed within "", which leads to SPACE-separated partial name items. So:

    20201323223_vendo.perfil01_17872513294967257_1601950878_live.mp4
    

    is changed to:

    "20201323223" "vendo.perfil01" "17872513294967257" "1601950878" "live.mp4"
    

    before looping. Within the loop implement an index counter and just append those items to a buffer whose index numbers lie within a certain range that depends on the total number of items.

    Here is an example script that demonstrates what I mean:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "_ROOT=%~dp0."           & rem // (full path to target directory)
    set "_MASK=*_*_*_*_live.mp4" & rem // (pattern to match file names)
    set "_FILT=^[0123456789][0123456789]*_..*_[0123456789][0123456789]*_[0123456789][0123456789]*_live\.mp4$"
                                   rem // (additional `findstr` filter for file names)
    set /A "_POS=1"              & rem /* (index of first `_`-separated item to extract;
                                   rem     `0` is the first item, `-1` is the last) */
    set /A "_NUM=-4"             & rem /* (number of `_`-separated items to extract;
                                   rem     `-1` means all up to the last item) */
    
    rem // Change into target directory:
    pushd "%_ROOT%" && (
        rem // Loop through all matching non-hidden, non-system files:
        for /F "delims= eol=|" %%F in ('
            dir /B /A:-D-H-S "%_MASK%" ^| findstr /I /R /C:"%_FILT%"
        ') do (
            rem // Store current file name, initialise item index, counter and buffer:
            set "FILE=%%F" & set /A "IDX=-1, CNT=-1" & set "BUFF=_"
            rem // Toggle delayed expansion to avoid troubles with `!`:
            setlocal EnableDelayedExpansion
            rem // Count number of items and store one less:
            rem set "TEST=%FILE:_=" & set /A "CNT+=1" & set "TEST=%"
            for %%I in ("!FILE:_=" "!") do set /A "CNT+=1"
            rem // Determine item index position from given index and number:
            if !_POS! lss 0 (set /A "BEG=CNT+_POS+1") else set /A "BEG=_POS"
            if !_NUM! lss 0 (set /A "END=CNT+_NUM+1") else set /A "END=_POS+_NUM-1"
            rem // Transport numbers over `endlocal` barrier:
            for %%C in (!CNT!) do for %%B in (!BEG!) do for %%A in (!END!) do (
                rem // Loop through `_`-separated items of file name:
                for %%I in ("!FILE:_=" "!") do (
                    rem // Store current item, increment item index:
                    endlocal & set "ITEM=%%~I" & set /A "IDX+=1"
                    setlocal EnableDelayedExpansion
                    rem // Append current item to buffer if in range:
                    if !IDX! geq %%B if !IDX! leq %%A (
                        rem // Transport buffer over `endlocal` barrier:
                        for /F "delims=" %%E in ("BUFF=!BUFF!_!ITEM!") do (
                            endlocal & set "%%E"
                            setlocal EnableDelayedExpansion
                        )
                    )
                )
            )
            rem // Return buffer:
            echo(!BUFF:~2!
            endlocal
        )
        rem // Return from target directory:
        popd
    )
    
    endlocal
    exit /B