Как скопировать файл в зависимости от размера файла сравнения? - PullRequest
0 голосов
/ 26 мая 2018

Существуют подкаталоги S и F, содержащие файлы с одинаковыми именами, но с разными размерами файлов (<2 МБ). <br>Я хочу скопировать файл из S в F, именно еслифайл из S меньше, чем файл из F.

FOR /R %%F IN ( >>THE_FILES_IN_S<< ) DO (
    set fileS="S/%%~nF"
    FOR /F "usebackq" %%A IN ('%fileS%') DO set sizeS=%%~zA
    set fileF="F/%%~nF"
    FOR /F "usebackq" %%A IN ('%fileF%') DO set sizeF=%%~zA
    if %sizeS% LSS %sizeF% (copy /V /Y %fileS% %fileF%)
)

Приведенный выше код не работает, поскольку >>THE_FILES_IN_S<< является псевдокодом.

Что является правильнымвыражение?

Есть ли другие ошибки (и какова правильная форма)?

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Ограничение на 32-битное целое число со знаком, равное ~ 2 ГБ, не применяется
при сравнении чисел в строках, дополненных нулями до равной длины.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BaseFolder=C:\Temp"

for %%S in ("%BaseFolder%\S\*") do (
    if exist "%BaseFolder%\F\%%~nxS" (
        for %%F in ("%BaseFolder%\F\%%~nxS"
            ) do Call :Check %%~zS %%~zF || copy /Y "%%S" "%%F" >nul
    )
)
endlocal
Goto :Eof
:Check
Set "S=00000000000000000000%1"
Set "F=00000000000000000000%2"
If %S:~-20% LSS %F:~-20% exit /B 1

Приведенный выше пакет позволяет избежать отложенного расширения путем передачи размеров.в подпрограмму и сравнение строк с 20 знаками после запятой, возвращающими уровень ошибки с меньшим результатом для копирования в этом состоянии ошибки.

0 голосов
/ 26 мая 2018

Использование переменных среды, определенных / измененных в командном блоке и на которые имеются ссылки в том же командном блоке, потребует использования отложенное расширение .Справка по выводу команды SET при запуске в окне командной строки set /? объясняет использование отложенного расширения на примере IF и FOR .

Лучше всего избегать использования отложенного расширения путем непосредственного использования переменных цикла вместо присвоения их значений переменным среды и последующей ссылки на значения переменных среды в командном блоке, начиная с ( и заканчивая сопоставлением ).

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BaseFolder=C:\Temp"

for %%S in ("%BaseFolder%\S\*") do (
    if exist "%BaseFolder%\F\%%~nxS" (
        for %%F in ("%BaseFolder%\F\%%~nxS") do (
            if %%~zS LSS %%~zF copy /Y "%%S" "%%F" >nul
        )
    )
)

endlocal

Заменить C:\Temp в третьей строке реальным путем к базовой папке.Если командный файл хранится в базовой папке, третья строка может быть заменена на:

rem Base folder is the directory containing the batch file.
set "BaseFolder=%~dp0"
rem Remove the backslash at end from batch file path.
set "BaseFolder=%BaseFolder:~0,-1%"

Внешний FOR выполняет поиск любого не скрытого файла в подкаталоге S базовой папки.соответствует шаблону подстановки * (любое имя) и присваивает полное имя файла переменной цикла S.

Если файл с таким же именем и расширением существует также в подкаталоге F базыпапка, выполняется еще один цикл FOR , который просто присваивает уже известное полное имя текущего файла в подкаталоге F переменной цикла F, а затем запускает еще один IF сравнение.

Внутреннее IF сравнивает с 32-разрядным целым числом со знаком сравнение размеров файлов двух файлов и копирует меньший файл в подкаталоге S в подкаталог F с подавлениемсообщение об успешном выводе COPY для обработки STDOUT путем перенаправления его на устройство NUL .

Обратите внимание, что этоПакетный файл s работает только для файлов с размером менее 2 ГБ из-за ограничения 32-разрядного целого числа со знаком командного процессора Windows на обработку целочисленных значений.

Весь приведенный выше пакетный код можно записать также в виде одной командной строки:

@for %%S in ("C:\Temp\S\*") do @if exist "C:\Temp\F\%%~nxS" for %%F in ("C:\Temp\F\%%~nxS") do @if %%~zS LSS %%~zF copy /Y "%%S" "%%F" >nul

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.

  • call /? ... объясняет %~dp0 (диск и путь аргумента 0 - командный файл)
  • copy /?
  • echo /?
  • endlocal /? ... здесь на самом деле не требуется и может быть удалено.
  • for /?
  • if /?
  • rem /?
  • set /?
  • setlocal /? ... здесь на самом деле не требуется и может быть удалено.
...