如何根据文件大小比较复制文件?

时间:2018-05-26 11:28:27

标签: windows batch-file command-line

子目录SF包含具有相同名称但文件大小不同的文件(<2 MB)。
我想将文件从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 :(得分:2)

32位有符号整数大小限制~2GB不适用
比较用左边填充的字符串中的数字到相等的长度。

@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个小数位进行比较来避免延迟扩展,在较小的结果上返回错误级别以复制此失败条件。

答案 1 :(得分:0)

在命令块中定义/修改并在同一命令块中引用的环境变量的使用需要使用delayed expansion。在命令提示符窗口set /?中运行时命令 SET 输出的帮助解释了 IF FOR 的延迟扩展的使用情况示例

最好是通过直接使用循环变量而不是将它们的值分配给环境变量来避免使用延迟扩展,然后在命令块中引用环境变量的值,以(开头并以匹配{{结尾1}}。

)

将第三行中的@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

外部 FOR 搜索与通配符模式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%" (任何名称)匹配的基本文件夹的子目录S中的任何非隐藏文件,并将完整限定的文件名分配给循环变量*

如果基本文件夹的子目录S中也存在具有相同文件名和文件扩展名的文件,则会再执行一次 FOR 循环,该循环只分配已知的完全限定文件名子目录F中的当前文件循环变量F,然后再运行一次 IF 比较。

内部 IF 与32位有符号整数比较两个文件的文件大小,并将子目录F中的较小文件复制到子目录S并抑制 COPY 输出的成功消息,通过将其重定向到设备 NUL 来处理 STDOUT

请注意,此批处理文件仅适用于小于2 GiB的文件,因为处理整数值时Windows命令处理器的32位有符号整数限制。

上面的整个批处理代码也可以作为单个命令行编写:

F

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • @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 /?(参数0的驱动器和路径 - 批处理文件)
  • %~dp0
  • copy /?
  • echo /? ...此处并不需要,可以删除。
  • endlocal /?
  • for /?
  • if /?
  • rem /?
  • set /? ...此处并不需要,可以删除。