用于复制和保留重复项的 Windows 批处理文件

Posted

技术标签:

【中文标题】用于复制和保留重复项的 Windows 批处理文件【英文标题】:Windows batch file to copy and keep duplicates 【发布时间】:2011-07-12 00:40:12 【问题描述】:

我有许多图像文件夹,我想创建一个批处理文件,可以查看所有这些目录及其子目录,并将每个图像复制到一个新文件夹(同一文件夹中的所有文件)。我使用以下方法进行此工作:

md "My new folder"
for /D %i in (*) do copy "%i\*" ".\My New Folder"

但是,我还想保留重复文件(例如,如果文件夹 1 和文件夹 2 都有名为 001.jpg 的图像,我希望将两者都复制到新文件夹中)。新文件名是什么对我来说并不重要!有:

001.jpg
001(1).jpg
001(2).jpg

会很棒,但即使只是用增量计数重命名每个文件并最终得到:

1.jpg
2.jpg
3.jpg
etc

也可以。我只需要使用标准的 .bat/.cmd 文件,不需要外部软件。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

以下脚本是 aflat 答案的改进版本。

脚本需要两个参数:SourcePath TargetPath。

它递归地将所有文件从 SourcePath 及其子文件夹复制到 TargetPath,仅当存在重复时,才会在基本名称后附加一个递增的计数器。

如果 TargetPath 已经存在,则会出错,因为可能已经存在带有 _n 后缀的名称。

如果您想为每个基本名称设置一个单独的计数器和/或如果您希望能够复制到现有文件夹,则需要做更多的工作。

脚本比简单的答案更健壮。例如,带有! 的名称就可以正常工作。它还以更直接和更有效的方式实现了aflat的算法。

::copyFlat sourcePath  TargetPath
@echo off
setlocal disableDelayedExpansion

:: Initialize and validate arguments
if "%~2" equ "" echo Error: Insufficient arguments>&2&exit /b 1
set "source=%~f1"
if not exist "%source%\" echo Error: Source folder "%source%" does not exist>&2&exit /b 1
set "target=%~f2"
if exist "%target%\" echo Error: Target folder "%target%" already exists>&2&exit /b 1

:: Do the work
md "%target%"
set /a n=0
for /r "%source%" %%F in (*) do if "%%~dpF" neq "%target%\" (
  if exist "%target%\%%~nxF" (
    set /a n+=1
    set "full=%%F"
    set "name=%%~nF"
    set "ext=%%~xF"
    setlocal enableDelayedExpansion
    copy "!full!" "!target!\!name!_!n!!ext!" >nul
    endlocal
  ) else copy "%%F" "%target%" >nul
)

【讨论】:

点赞,代表user【参考方案2】:

这应该适合你。它在扩展名后附加一个数字,但您可以轻松地将其移动到任何地方。我从 .\src 目录复制了文件,因为如果您的源与批处理文件处于同一级别,批处理文件也会尝试评估 test_folder。最好的选择是对 test_folder 进行硬编码,这样它就不会被 DIR /S /B... 命令评估

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set TESTFOLDER=test_folder
md "%TESTFOLDER%"

set /a counter=0
FOR /F "tokens=*" %%i IN ('DIR /S /B /A-D .\src\*') DO FOR /F "tokens=*" %%j IN ('DIR /B "%%i"') DO IF EXIST ".\%TESTFOLDER%\%%j" (
        set /a counter=!counter!+1
        echo folder: %TESTFOLDER%
        copy "%%i" ".\%TESTFOLDER%\%%j_!counter!"
    ) ELSE copy "%%i" ".\%TESTFOLDER%\%%j"
:eof

【讨论】:

如果任何名称包含!,这将失败。可以通过在循环内打开和关闭延迟扩展来修复。【参考方案3】:

或者您可以安装 git bash (https://git-for-windows.github.io/) 并运行以下命令:

mv --backup=numbered src\*.* destinationFolder

这将创建类似于 filename.ext.~1~、filename.ext.~2~ ... 的文件 这对您来说可能已经足够了,在我的情况下,我不喜欢丢失原始文件扩展名,因此您可以通过在目标文件夹中运行以下命令来重命名它:

ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & \1.\3.\2/'

这将打印重命名命令,如下所示: mv filename.ext.~1~ filename.1.ext

一旦您对想要执行这些命令感到满意,请再次运行相同的命令,但要像这样执行管道到 sh(请注意,与最终重命名相同的任何现有文件都将被覆盖 - 但 -i 选项应该保护你):

  ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & \1.\3.\2/' | sh

改编自这个答案 (https://***.com/a/2372739)

【讨论】:

以上是关于用于复制和保留重复项的 Windows 批处理文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MongoDB 中保留重复项的同时进行递归查找

在保留顺序函数的同时删除向量中的重复项的逻辑错误

拷贝和删除文件

用于计算重复项的 SQL 查询 [重复]

文件操作:mv 和cp命令用法

如何从包含 JavaScript 中重复项的数组中获取唯一值数组? [复制]