Estou tentando fazer uma operação de substituição de string em todos os arquivos, exceto aqueles na pasta .git e em todos os diretórios pycache que podem aparecer aninhados em qualquer diretório aninhado. Estou executando o script no diretório raiz que contém uma pasta .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!
)
)
)
Mas estou preso na condição if deste loop, que ainda imprime todos os arquivos da pasta .git, mesmo que seja excluído usando if not "%%~dpF"==".git\"
. Por que? Não consigo encontrar nenhuma solução para isso, nem o chat gpt pode me dizer. Como é possível que a IA não saiba disso? Também if not "%%~dpF"=="%CD%\.git\"
não funciona.
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
que ainda imprime os arquivos nas pastas .git e __pycache__. Isso é tão fácil de conseguir usando 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
Então não entendo por que é tão complicado fazer o mesmo nos arquivos .bat do Windows? O que da?
Esta não é uma resposta completa. Apenas um exemplo usando PowerShell.
Salve-o em um arquivo com extensão
.ps1
. Ex:test.ps1
e coloque-o em seu diretório de trabalho. Para executar,Right Click
>Run with PowerShell
.Isso exibirá todos os arquivos e diretórios, exceto no filtro
$WL1
$WL2
Você pode adicionar um arquivo ou pasta a ser excluído por sua extensão em
$WL1
, e por seu nome em$WL2
.Para verificar todos os filtros disponíveis, você pode digitar
Get-ChildItem -Recurse | Get-Member
ouGCI -R|GM
no Console do PowerShell no diretório.Embora os scripts do PowerShell sejam muito mais fáceis de escrever e ler do que o script em lote comum, falta uma coisa: é muito difícil para o usuário médio executá-los, já que você não pode simplesmente clicar duas vezes neles.
Porém, existem soluções fáceis, sendo as duas mais comuns:
O fácil
Escreva seu script do PowerShell normalmente. Em seguida, crie um script cmd no qual você coloca o arquivo
powershell.exe -ExecutionPolicy Bypass -NoProfile -NoLogo -File "%~dp0\MyPowerShellFile.ps1
. Agora você pode fornecer aos usuários os dois arquivos e eles podem simplesmente clicar duas vezes no arquivo bat como estão acostumados e ele executará o script do PowerShell.Isso torna mais fácil para os usuários (e para você) usar arquivos em lote, ao mesmo tempo que obtém todo o poder do PowerShell. A desvantagem é que agora você tem dois arquivos, o que nos leva a:
Apenas um arquivo
Semelhante ao anterior, mas em vez de chamar um arquivo separado, você também pode integrar todo o seu script no arquivo em lote e evitar a necessidade de dois arquivos.
Você pode fazer isso usando o
-EncodedCommand
parâmetro para passar uma string codificada em base64 para o PowerShell que conterá todo o seu script.Uma função simples do PowerShell (divirta-se escrevendo o código equivalente em cmd..) que pega qualquer arquivo PS1 e cria um arquivo bat é a seguinte:
Fonte porque não tenho minha coleção de scripts em mãos - mas parece correta.