简体   繁体   中英

Batch script to match two filenames in the same folder with different extension

I've been looking, but I don't quite understand the regex of matching filenames. I have seen in SO that there are questions that match two filenames in different folders, but I'm looking within the same folder.

file01.jpg
file01.wav
file02.jpg
file03.jpg
file04.jpg
file04.wav

I want it to match if there is a jpg and a wav to run a ffmpeg script, and if the wav doesn't have a matching jpg then run another ffmpeg script, and if there is no matching wav to the jpg do another script.

if( $jpg == $wav ) // matching filenames without extension
    do script1
else if( $jpg != $wav ) // if there is no matching jpg to wav
    if( empty($jpg) && $wav )
        do script2
    if( empty($wav) && $jpg )
        do script3

Powershell solution:

    set-location 'd:\mydirectory'

    $files      = ls "*.*"
    $dictionary = @{}

    foreach($file in $files) {
        $dictionary[$file.BaseName] += @( $file.Extension.ToLower() )
    }

    foreach($key in $dictionary.keys) {

        if( $dictionary[$key].Count -gt 1 ) {
            Write-Host $key ': wav and jpg'
        }
        elseif( $dictionary[$key] -eq '.wav' ) {
            Write-Host $key ': wav only'
        }
        elseif( $dictionary[$key] -eq '.jpg' ) {
            Write-Host $key ': jpg only'
        }
    }

You have not provided any code of your own, so I will only lead you in the right direction, and not give you a complete answer.

for %%i in (*.wav) do for %%a in (*.jpg) do if "%~ni"=="%~na" echo "%%i" = "%%a"

We just match the name only, excluding extension of all wav files by %%~ni with the name only, no extensions of all jpg files %~na and simply do something with the result, in this case I echo both files.

For a better understanding of how the variable handling works, in cmd.exe run for /?

Just to make things simpler to understand, I thought I'd post a method which breaks this down into separate procedures for you.

The idea is to list the file names matching the extensions within individual holding files. Then use FindStr to determine which lists hold unique or duplicate names before deleting the holding files.

@Echo Off
Set "sd=C:\SomePath\To\YourFiles"
Set "e1=.jpg"
Set "e2=.wav"

Rem change working directory to source directory
CD /D "%sd%" 2>Nul || Exit /B

Rem Write files names matching extension spec to .tmp files
For %%A in (%e1% %e2%) Do (For /F "Delims=" %%B In (
        'Dir /B/A-D-S-L "*%%A" 2^Nul') Do Echo "%%~nB")>"x%%A.tmp"

Rem %e1% files only, ["%%~A%e1%"]
For /F "Delims=" %%A In ('FindStr /XLVIG:"x%e2%.tmp" "x%e1%.tmp"') Do (
    Echo %%~A%e1%
)
Echo(

Rem %e2% files only, ["%%~A%e2%"]
For /F "Delims=" %%A In ('FindStr /XLVIG:"x%e1%.tmp" "x%e2%.tmp"') Do (
    Echo %%~A%e2%
)
Echo(

Rem Both %e1% and %e2% files, ["%%~A%e1%", "%%~A%e2%"]
For /F "Delims=" %%A In ('FindStr /XLIG:"x%e2%.tmp" "x%e1%.tmp"') Do (
    Echo %%~A%e1%, %%~A%e2%
)
Echo(

Rem Delete the tmp files
Del "x%e1%.tmp" "x%e2%.tmp" >Nul 2>&1

Rem pause to show screen output
Pause

Just ensure that the location in line 2 is modified to match your source directory, to test it.

If you are happy that it has correctly identified the files, you can replace the Echo lines on 15 , 21 and 27 with your own commands, (I have left the file names in brackets in the Rem arks as a reminder) . You can optionally remove lines 17 , 23 , 29 , 34 and 35 , those containing Rem arks and any empty lines as you wish.

An answer with both a batch and a powershell solution following similar routes. Doing a dir with *.jpg *.wav and sorting by name.

The PowerShell script sorting -unique thus eliminating dupes and checking the existence of .wav and .jgp .

## Q:\Test\2018\05\24\MatchFiles.ps1
Get-ChildItem *.wav,*.jpg|Sort-Object BaseName -Unique|ForEach-Object {
    If ((Test-Path ("{0}.wav" -f $_.BaseName )) -and
        (Test-Path ("{0}.jpg" -f $_.BaseName )) ) {
        "$($_.BaseName) Both exist"
    } elseIF (!(Test-Path ("{0}.wav" -f $_.BaseName))){
        "$($_.BaseName).wav missing"
    } else {
        "$($_.BaseName).jpg missing"
    }
}

The batch variant also sorting but checking the output if previous entry had the same filename.

:: Q:\Test\2018\05\24\MatchFiles.cmd
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
Set "Last="
For /f "delims=" %%A in ('dir /B *.wav *.jpg^|sort') Do (
    If defined Last If "%%~nA" Equ "!Last!" (
        Echo %%~nA Both exist
    ) else ( 
        if "%%~xA" equ ".wav" (
            echo %%~nA.jpg missing
        ) else (
            if not exist "%%~nA.wav" echo %%~nA.wav missing
        )
    )
    Set "Last=%%~nA"
)

They share the very same output (added a single file05.wav for input):

file01 Both exist
file02.wav missing
file03.wav missing
file04 Both exist
file05.jpg missing

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM