Windows 批处理文件复制并保留重复项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5248393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Windows batch file to copy and keep duplicates
提问by David Lee
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:
但是,我也想保留重复的文件(例如,如果文件夹 1 和文件夹 2 都有名为 001.jpg 的图像,我希望将它们都复制到新文件夹中)。新文件名是什么对我来说并不重要!拥有:
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.
也会好的。我只需要使用标准的 .bat/.cmd 文件,不需要外部软件。
Thanks for your help!
谢谢你的帮助!
回答by aflat
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
这应该对你有用。它在扩展名后附加一个数字,但您可以轻松地将其移动到任何地方。我从 .\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
回答by dbenham
The following script is an improved version of aflat's answer.
以下脚本是 aflat 答案的改进版本。
The script expects two arguments: SourcePath TargetPath.
该脚本需要两个参数: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.
它递归地将所有文件从 SourcePath 及其子文件夹复制到 TargetPath,仅在存在重复项时才将递增计数器附加到基本名称。
It errors out if the TargetPath already exists because there may already exist names with the _n suffix.
如果 TargetPath 已经存在,则会出错,因为可能已经存在带有 _n 后缀的名称。
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.
该脚本比 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
)
回答by Haemoglobin
Or you can install git bash (https://git-for-windows.github.io/) and run the following:
或者您可以安装 git bash ( https://git-for-windows.github.io/) 并运行以下命令:
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:
这将创建看起来像 filename.ext.~1~, filename.ext.~2~ 的文件......这对你来说可能已经足够了,在我的情况下,我不喜欢丢失原始文件扩展名,所以你可以重命名它通过在目标文件夹中运行以下命令:
ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & ../'
This will print the rename commands like so: mv filename.ext.~1~ filename.1.ext
这将打印重命名命令,如下所示: 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):
一旦您对要执行这些命令感到满意,请再次运行相同的命令,但通过管道连接到 sh 将像这样执行(请注意,与最终重命名相同的任何现有文件都将被覆盖 - 但 -i 选项应该保护您):
ls *~ | sed 's/\(.*\)\.\(.*\)\.~\(.*\)~/mv -i & ../' | sh
Adapted from this answer (https://stackoverflow.com/a/2372739)
改编自这个答案(https://stackoverflow.com/a/2372739)