批处理文件,以查找所有图像并复制到文件夹

时间:2013-01-03 19:01:11

标签: batch-file vbscript cmd

甚至不确定这是否可行,但我想我会尝试一下。

所以这是我的问题。我需要为所有图像搜索多个大硬盘(1TB和更大)并将它们移动到一个文件夹。我遇到的问题是无论我试着写什么语言,我似乎无法找到答案。我想要它是vbs或bat相关不使用robocopy命令。我的一些驱动器都是不同的格式,如fat32和ntfs。我用批处理文件尝试的一些脚本的问题是我的文件名太长了。所以我需要它做的主要功能是找到图像,复制它们,如果它们存在则用_001 _002重命名它们,计算移动了多少文件,然后最后删除它们或将它们移动到一个单独的文件夹进行删除(a在我眼里更安全一点)。任何帮助将不胜感激,因为我完全被这个难以接受。

这是我正在处理的一个脚本,但刚刚停止。这个问题是它复制了文件,但由于某种原因没有保留扩展名。这是我在网上找到的,并稍微修改了代码。我对代码非常熟悉,但由于某些原因似乎无法解决这个问题。

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


set /a counter=0
FOR /F "tokens=*" %%i IN ('DIR /S /B /A-D C:\Users\user1\Desktop\*.jpg') 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 /B "%%i" ".\%TESTFOLDER%\%%j"
:eof

编辑:下面的VBScript代码

Set fso = CreateObject("Scripting.FileSystemObject")

testfolder = ".\allpictures"
'fso.CreateFolder(testfolder)

CopyFiles fso.GetFolder("E:\")

Sub CopyFiles(fldr)
  For Each f In fldr.Files
    basename  = fso.GetBaseName(f)
    extension = fso.GetExtensionName(f)
    If LCase(extension) = "jpg" Then
      dest  = fso.BuildPath(testfolder, f.Name)
      count = 0
      Do While fso.FileExists(dest)
        count = count + 1
        dest  = fso.BuildPath(testfolder, basename & "_" & count & "." _
          & extension)
      Loop
      f.Copy dest
    End If
  Next

  For Each sf In fldr.SubFolders
    CopyFiles sf
  Next
End Sub

3 个答案:

答案 0 :(得分:3)

你不该做什么:不要让你被蒙骗

  1. 在您完全理解问题之前生成代码,并详细了解该过程。 (没有人喜欢“给我一个程序来解决我的问题”类型的问题,有时候代码片段可能会澄清一个问题,但是要求人们尝试他们认为不能做的事情就是糟糕的教诲。)
  2. 从一种新语言开始,以解决手头的问题(计划或没有计划)。 (如果你不习惯用你的母语写一封情书,有什么机会用一种语法和外国词汇来表达它?)
  3. 你应该做什么

    1. 考虑您的问题,关注最终目标:组织您的图像(如果我理解您的评论正确)。那会是什么样子?当然不是一个包含数千个带有错位名称的文件的文件夹。我会努力以一个文件夹树结束,其中包含具有良好名称的.jpgs,或者包含有关我的图片(视频?)的适当元信息的数据库,并将其存储到存储中,甚至上传到某个云存储。从最终目标向后工作:在上一步中你需要什么。

    2. 我假设,第一步是所有.jpgs的列表。什么是 - 根据您的知识,技能和工具 - 获取此列表的最简单方法是什么?可能是dir /s [/b] c:\*.jpg > jpglist.txt的一些变体。对于以后出现的许多驱动器或其他扩展,您可以在一个.cmd文件(>/>>)中组合许多这样的行。此列表和文本编辑器或一些过滤和电子表格可以为您提供有关您的任务的重要信息:多少个文件?各种尺寸的总和?重复的文件名?可能的分类?

    3. 购买新的外置硬盘(你现在知道它的大小)。这样,在向精彩的观众展示精美的收藏品后,您可以将删除推迟到步骤。 [这最后一项任务很简单:只需通过“删除”过滤器脚本提供jpglist.txt或使用文本编辑器的搜索和替换功能将"del /Q "放在行的开头。]

    4. 根据您的需求和技能,您可以将基本的jpglist.txt转换为具有相关信息的新.csv文件,可以通过电子表格程序手动扫描/检查和/或以编程方式使用生成文件或文件夹名称(附加数字应该是最后一个后备)。如果您想要一些JPG元数据并且不知道如何,您可以在这里询问(然后甚至显示您用于获取这些文件的大小或日期的代码)。

    5. 使每个步骤都可重复且尽可能具有非破坏性(例如,在完成所有操作之前,不要移动或删除无法使用一个命令重新创建的文件)。使用你知道的技术/工具;这肯定排除了“在互联网上找到的代码”);如果你想学习新的东西/更有趣,那么在玩具项目中做。

答案 1 :(得分:1)

为操作系统附带的脚本解释器可以轻松处理的内容安装新的脚本解释器是不合适的。

您的脚本不维护扩展名的原因是您在文件名的末尾附加了计数器变量的内容,因此foo.jpg变为foo.jpg1,计数器值为1你必须使用修饰符来避免这种情况:%%~nj只提供文件的名称(没有路径和扩展名),%%~xj只是扩展名。此外,您可能不希望所有文件都有一个计数器,但每个重复文件名只需一个计数器。

@echo off

setlocal EnableDelayedExpansion

set TESTFOLDER=allpictures
md "%TESTFOLDER%"

for /f "tokens=*" %%i in ('dir /s /b /a-d C:\Users\user1\Desktop\*.jpg') do (
  call :copyfile "%%~i"
)

goto :eof

:copyfile
set fname=%~nx1
set counter=0

if not exist ".\%dest%\!fname!" goto docopy

:recheck
if exist ".\%dest%\%~n1_!counter!%~x1" (
  set /a counter+=1
  goto recheck
)
set fname=%~n1_!counter!%~x1

:docopy
copy "%~1" ".\%dest%\!fname!"

goto :eof

endlocal

在VBScript中你可以这样做:

Set fso = CreateObject("Scripting.FileSystemObject")

testfolder = ".\allpictures"
fso.CreateFolder(testfolder)

CopyFiles fso.GetFolder("C:\Users\user1\Desktop")

Sub CopyFiles(fldr)
  For Each f In fldr.Files
    basename  = fso.GetBaseName(f)
    extension = fso.GetExtensionName(f)
    If LCase(extension) = "jpg" Then
      dest  = fso.BuildPath(testfolder, f.Name)
      count = 0
      Do While fso.FileExists(dest)
        count = count + 1
        dest  = fso.BuildPath(testfolder, basename & "_" & count & "." _
          & extension)
      Loop
      f.Copy dest
    End If
  Next

  For Each sf In fldr.SubFolders
    CopyFiles sf
  Next
End Sub

答案 2 :(得分:-2)

如果使用perl,你可以对给定目录中的所有文件进行全局处理,并将它们放入数组中。 my @Files = glob '<directory>\*.jpg';

使用循环foreach $file (@Files){ ... }

浏览每个文件

每个.jpg在循环中称为$file。您可以通过获取文件名    my ($originalfilename) = $file;并添加您想要的任何扩展名,然后将其复制/移动到您想要的任何其他目录。此外,在该循环中,您可以递增计数器循环或仅获取数组的标量值。

HERE上有大量关于perl文档和教程的内容。如果文件操作将是常见的,那么值得学习一些基本的perl。