Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于复制和保留副本的Windows批处理文件_Windows_Batch File_Copy_Cmd_Rename - Fatal编程技术网

用于复制和保留副本的Windows批处理文件

用于复制和保留副本的Windows批处理文件,windows,batch-file,copy,cmd,rename,Windows,Batch File,Copy,Cmd,Rename,我有许多图像文件夹,我想创建一个批处理文件,可以查看所有这些目录及其子目录,并将每个图像复制到一个新文件夹(同一文件夹中的所有文件)。我使用以下工具完成此工作: md "My new folder" for /D %i in (*) do copy "%i\*" ".\My New Folder" 但是,我还希望保留具有副本的文件(例如,如果folder1和folder2都有名为001.jpg的图像,我希望两者都复制到新文件夹)。新文件名是什么对我来说并不重要!具有: 001.jpg 001(

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

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文件,但没有外部软件


谢谢你的帮助

这应该适合你。它会在扩展名后附加一个数字,但您可以轻松地将其移动到任何位置。我从.\src目录复制了文件,因为如果源与批处理文件处于同一级别,批处理文件也会尝试评估test_文件夹。最好的选择是硬编码测试_文件夹,这样它就不会被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

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

脚本需要两个参数:SourcePath TargetPath

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

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

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

该脚本比aflat答案更健壮。例如,带有
的名称工作正常。它还以更直接、更高效的方式实现了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
)

或者,您可以安装git bash()并运行以下操作:

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选项应保护您):


根据此答案改编()

如果任何名称包含
,则此操作将失败。可以通过代表在loop.upvote内打开和关闭延迟表达式来修复
  ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & \1.\3.\2/' | sh