Script batch Windows : comment parcourir récursivement tous les fichiers sauf certains types de fichiers et dossiers ?

J’essaie de faire une opération de remplacement de chaîne sur tous les fichiers sauf ceux du dossier .git et tous les répertoires pycache qui peuvent apparaître imbriqués dans n’importe quel répertoire imbriqué. J’exécute le script dans le répertoire racine qui contient un dossier .git.

for /r /d %%F in (*) do (
    echo Checking: %%F
    if not "%%~xF"==".sh" if not "%%~xF"==".png" if not "%%~xF"==".bat" if not "%%~dpF"=="__pycache__\" if not "%%~dpF"==".git\" (
        echo Found file: %%F
        findstr /C:"{{ADDON_NAME_PACKAGE}} {{ADDON_NAME}} {{ADDON_NAME_FULL}}" "%%F" >nul 2>&1
        if not errorlevel 1 (
            echo %%F
            set "file=%%F"
            setlocal DisableDelayedExpansion
            set "cmd=sed -i -e ""s/%replace_package%/%package_name%/g"" -e ""s/%replace_addon_name%/%addon_short_name%/g"" -e ""s/%replace_addon_name_full%/%addon_full_name%/g"" ""!file!""
            endlocal & !cmd!
            echo Replaced placeholders in !file!
        )
    )
)

Mais je suis bloqué dans la condition if de cette boucle qui affiche toujours tous les fichiers du dossier .git même s’il est exclu avec if not "%%~dpF"==".git\". Pourquoi ? Je ne trouve aucune solution à ça, même ChatGPT ne peut pas me le dire. Comment est-ce possible que l’IA ne connaisse pas ça ? De plus if not "%%~dpF"=="%CD%\.git\" ne fonctionne pas non plus.

for /r /d %%F in (*) do (
    echo Checking: %%F
    if not "%%~xF"==".sh" if not "%%~xF"==".png" if not "%%~xF"==".bat" if not "%%~dpF"=="__pycache__\" if not "%%~dpF"==".git\" (
        echo Found file: %%F

ce qui affiche toujours les fichiers dans le dossier .git et les dossiers pycache. C’est tellement facile à réaliser sous Unix/Linux

replace_package="{{ADDON_NAME_PACKAGE}}"
replace_addon_name="{{ADDON_NAME}}"
replace_addon_name_full="{{ADDON_NAME_FULL}}"

perform_replacements() {
    local file="$1"
    local package_name="$2"
    local addon_short_name="$3"
    local addon_full_name="$4"

    sed -i "s/${replace_package}/${package_name}/g; s/${replace_addon_name}/${addon_short_name}/g; s/${replace_addon_name_full}/${addon_full_name}/g" "$file"
}

find . \( -name .git -o -name __pycache__ \) -prune -o \( -type f -not -name "*.sh" -not -name "*.png" \) -print0 | while IFS= read -r -d '' file; do
    perform_replacements "$file" "$package_name" "$addon_short_name" "$addon_full_name"
    echo "Replaced placeholders in $file"
done

Donc je ne comprends pas pourquoi c’est si compliqué dans les fichiers .bat sous Windows de faire la même chose ? Qu’est-ce qui se passe ?

Ce n’est pas une réponse complète. Seulement un exemple utilisant PowerShell.

Enregistrez-le dans un fichier avec l’extension .ps1. Ex : test.ps1, et placez-le dans votre répertoire de travail. Pour l’exécuter, Clic droit > Exécuter avec PowerShell.

  • Format officiel
$WL1 = @('.bat', '.png', '.sh', '.ps1')
$WL2 = @('.git', '__pycache__')
if ($PWD.Path -ne $PSScriptRoot) {Push-Location -Path $PSScriptRoot}
Get-ChildItem -Recurse | Where {$_.Name -notin $WL2 -and $_.Extension -notin $WL1} |
ForEach-Object {$_.Name}
pause

Cela affichera tous les fichiers et répertoires sauf ceux dans les filtres $WL1 $WL2

Vous pouvez ajouter un fichier ou dossier à exclure par son extension dans $WL1, et par son nom dans $WL2.

  • Format court
$WL1='.bat','.png','.sh','.ps1'
$WL2='.git','__pycache__'
Pushd $PSScriptRoot
GCI -R|? Name -notin $WL2|? Extension -notin $WL1|% Name
pause

Pour vérifier tous les filtres disponibles, vous pouvez taper Get-ChildItem -Recurse | Get-Member ou GCI -R|GM dans la console PowerShell dans le répertoire.