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

发布于 2024-10-21 02:14:47 字数 480 浏览 7 评论 0原文

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

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

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

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

会很棒,但即使只是用增量计数重命名每个文件并以: 结尾

1.jpg
2.jpg
3.jpg
etc

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

感谢您的帮助!

I have many folders of images, and I want to create a batch file that can look through all these directories and their subdirectories, and copy every image to a single new folder (all files in the same folder). I have this working using the below:

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

however, I also want to keep files with duplicates (for example if folder1 and folder2 both have images called 001.jpg, i want both copied to the new folder). It doesn't matter to me what the new filenames are! Having:

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

would be great, but even just renaming every single file with an incremental count and ending up with:

1.jpg
2.jpg
3.jpg
etc

would be fine too. I need it just using a standard .bat/.cmd file though, no external software.

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

信愁 2024-10-28 02:14:47

以下脚本是 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
)

The following script is an improved version of aflat's answer.

The script expects two arguments: SourcePath TargetPath.

It recursively copies all files from SourcePath and its subfolders to TargetPath, appending an increasing counter to the base name only if there is a duplicate.

It errors out if the TargetPath already exists because there may already exist names with the _n suffix.

More work is needed if you want a separate counter for each base name and/or if you want to be able to copy to an existing folder.

The script is more robust than the aflat answer. For example, names with ! work just fine. It also implements aflat's algorithm in a more direct and more efficient way.

::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
)
墨小墨 2024-10-28 02:14:47

这应该对你有用。它在扩展名后面附加一个数字,但您可以轻松地将其移动到任何地方。我从 .\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

This should work for you. It appends a number after the extension, but you could easily move that anywhere. I copied files from the .\src dir, since if you have the sources at the same level as the batch file, the batch file tries to evaluate test_folder too. The best choice would be to hardcode test_folder so it is somewhere that won't be evaulated by the DIR /S /B... command

@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
も让我眼熟你 2024-10-28 02:14:47

或者你可以安装 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://stackoverflow.com/a/2372739< /a>)

Or you can install git bash (https://git-for-windows.github.io/) and run the following:

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

This will create files that look like filename.ext.~1~, filename.ext.~2~ ...
This may be enough for you, in my case I didn't like losing the original file extension so you can rename that by running the below in the destination folder:

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

This will print the rename commands like so:
mv filename.ext.~1~ filename.1.ext

Once you are happy that you want to execute these commands, run the same command again but pipe to sh to be executed like so (be aware any existing files the same as the final rename will be overwritten - but the -i option should protect you):

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

Adapted from this answer (https://stackoverflow.com/a/2372739)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文