для разделения файлов при сравнении файлов
Я совершенно не программист, но мне понадобится .bat-скрипт, чтобы что-то сделать. Один из них — сравнение файлов. У меня будет 2 каталога с несколькими zip-файлами, и мне нужно их сравнить (с помощью простой команды fc).
C:\ |__DIR 1
| |_ a.zip
| |_ b.zip
| |_ c.zip
| |_...
|
|__DIR 2
|_ a.zip
|_ b.zip
|_ c.zip
|_...
Я пытаюсь получить файлы в переменной, но это всегда терпит неудачу... При использовании:
SET "dir_A=C:\DIR 1"
SET "dir_B=C:\DIR 2"
for %%a in ("%dir_A%\*.zip") do ( echo %%a )
Выход:
C:\DIR 1\a.zip
C:\DIR 1\b.zip
C:\DIR 1\c.zip
Когда используешь:
for /f "delims" %%a in ('dir /b %dir_A%\^*.zip') do ( echo %%a )
Выход:
a.zip
b.zip
c.zip
и когда я использую:
for /f "delims=" %%a in ('dir /b %dir_A%\^*.zip') do (
set "filename=%%a"
echo %filename%
)
Я получу: Выход
ECHO is off.
ECHO is off.
ECHO is off.
Есть ли способ поместить файлы в переменную, чтобы я мог ее использовать? Я хочу использовать его в файле bat, например: for *.zipfile => имя файла...
fc %dir_A%\%filename% %dir_B%\%file > nul
if errorlevel 1 goto error
else...
2 ответа
1. Вам не нужно использовать этот побег
^
в
^*.zip
, убери это.
for /f "delims" %%a in ('dir /b %dir_A%\ ^ *.zip') do echo %%a
for /f "delims" %%a in ('dir /b %dir_A%\*.zip') do echo %%a
2. Вы работаете с папкой (DirSpace1
), в имени которых есть пробел, поэтому используйте двойные кавычки""
.
for /f "delims" %%a in ('dir /b %dir_A%\*.zip') do echo %%a
for /f "delims" %%a in ('dir /b "%dir_A%\*.zip"') do echo %%a
3. Правильный способ удаления разделителей использует
=
=>"delims="
илиdelims^= %%...
:
for /f "delims?" %%a in ('dir /b %dir_A%\*.zip') do echo %%a
for /f "delims=" %%a in ('dir /b "%dir_A%\*.zip"') do echo %%a
:: or..
for /f delims^= %%a in ('dir /b "%dir_A%\*.zip"') do echo %%a
4. Вы сохраняете значение файла в переменной и всегда заменяете его новым именем в цикле. Было бы полезно предложить вам принять имя, которое можно увеличить по имени, чтобы присвоить значение в рабочем файле цикла с помощью файл, но это немного усложняет ситуацию:
@echo off && setlocal
set "_dir_A=C:\DIR 1"
set "_dir_B=C:\DIR 2"
set /a "_cnt=0, _ledz=1000"
for /f delims^= %%G in =;(' @where.exe "%_Dir_A%:*.zip" ');= do =;(
2>nul where.exe "%_Dir_B%:%%~nxG" 1>nul && =;(
@call set^ /a "_num=%%_ledz%%+%%_cnt%%"
@call set^ "_A_%%_num:~-3%%=%%~nxG"
@call set^ /a "_cnt+=1"
);= || call %:^O "%%~G"
);=
call set^ /a "_cnt-=1"
for /l %%L in =;( 0, 1,%_cnt%);= do call set^ /a "_x=%%_ledz%%+%%~L" && =;(
"%ComSpec%" /v:on /q /s /c "echo/File !_x:~-3!: "!_A_%%_x:~-3%%!"" );=
%:^O
if "%~nx1" == "" endlocal && goto =:eof
echo/ERROR: "%%_Dir_B%%\%~nx1" & exit /b
Дополнительные ресурсы:
Расширения переменных в пакетных файлах CMD обрабатываются иначе, чем в других языках – не как часть выполнения команды, а как часть анализа входных данных (т. е. на очень ранней стадии, во многом аналогично макросам препроцессора C).
Итак%filename%
расширяется только один раз, когдаfor
строки читаются (вся группа считывается как единое целое) – в этот момент она расширяется до одной строки – и хотя переменная меняется на каждой итерации,echo
команда не расширяется повторно.
Есть несколько обходных путей, которые вы можете использовать:
Вместо этого напишите PowerShell. У него есть свои особенности (и иногда все равно приходится вызывать Cmd с помощью
cmd /c
), но в целом по поведению он намного ближе к стандартным языкам.$dirA = "C:\foo" get-childitem -recurse "$dirA\*.zip" | foreach-object { $file = $_ $filename = $_.Name echo "Got '$filename' which was last touched $($file.LastWriteTime)" }
Вместо этого напишите Python.
from pathlib import Path dirA = Path("C:/foo") for item in dirA.glob("*.zip"): print(f"Got {item.name} (at {item})")
Вместо использования
(...)
группы, перевести операции под свое:label
что ты сможешь тогдаcall
как подпрограмма. (Не забудьте в конце перейти на :EOF.)@echo off & setlocal for [...] do call :HandleFile "%%~a" goto :EOF :HandleFile set fullpath=%1 set filename=%~nx1 echo Got %filename% (full path %fullpath%) goto :EOF
Включите «отложенное расширение», которое активирует второй вид расширения с помощью
!variable!
это происходит позже в процессе. (И иногда вызывает собственную головную боль, поскольку применяется даже к результатам %-разложения!)@echo off & setlocal enabledelayedexpansion for [...] do ( set fullpath=%%a set filename=%%~nxa echo Got !filename! (full path !fullpath!). )