0

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

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

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

@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
4

3 回答 3

3

你不应该做的事情:不要让你被蒙蔽

  1. 在您完全理解问题并制定有关该过程的详细计划之前生成代码。(没有人喜欢“给我一个程序来解决我的问题”类型的问题,有时一个代码片段可能会澄清一个问题,但要求人们尝试他们承认不能做的事情是糟糕的教学。)
  2. 从一种新的语言开始解决手头的问题(计划或没有计划)。(如果你被困在用你的母语写一封情书,用外语的语法和词汇来写情书的机会有多大?)

你应该做什么

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

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

  3. 购买一个新的外部驱动器(你现在知道大小)。这样,您可以在向惊讶的观众展示您精心组织的收藏后将删除推迟到该步骤。[最后一项任务很简单:只需通过“删除”过滤器脚本输入 jpglist.txt 或使用文本编辑器的搜索和替换功能将其放在"del /Q "行首。]

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

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

于 2013-01-03T22:48:49.460 回答
1

对于操作系统附带的脚本解释器可以轻松处理的东西安装新的脚本解释器是矫枉过正的。

您的脚本不维护扩展名的原因是因为您将计数器变量的内容附加到文件名的末尾,因此计数器foo.jpg值为foo.jpg11。您必须使用修饰符来避免这种情况:%%~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
于 2013-01-03T23:01:05.660 回答
-2

如果使用 perl,您可以将给定目录中的所有文件都放在一个数组中。my @Files = glob '<directory>\*.jpg';

循环遍历每个文件 foreach $file (@Files){ ... }

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

网上有很多关于perl文档和教程的东西。如果文件操作很普遍,那么学习一些基本的 perl 是值得的。

于 2013-01-03T21:34:26.967 回答