【问题标题】:batch file that remembers what was copied [closed]记住复制内容的批处理文件[关闭]
【发布时间】:2015-12-15 18:13:23
【问题描述】:

这是我需要“扩展”的最初问题 Creating folder from file, copy initial file into folder and add prefix

这是输出批次

for /f "tokens=*" %%A in ('dir /b *.mp4') do (
    md "%%~nA"
    copy "%%~fA" "%%~nA\prefix_%%~nxA"
)

(如果有 .mp4,创建一个具有该文件名的文件夹并将 .mp4 复制到该文件夹​​中)

现在批处理文件应该“记住”创建了哪个文件夹,这样每次删除新创建的文件夹时它就不会重新启动相同的操作。 我在想“将名称写入 .txt,然后从 bat 上方执行休息”,每个新的批处理任务都可以检查名称是否存在。如果没有 = 复制,如果是 = 什么也不做。

【问题讨论】:

  • 您想使用IF NOT EXIST 命令。
  • 你的问题不清楚。可能是几个 .mp4 文件?假设:1. 文件是“one.mp4”,所以它被复制到“one\one.mp4”。 2. 新创建的文件夹“one”被删除。 问题:如果再次处理“one.mp4”文件怎么办?只是不要复制它?
  • 几个mp4文件,如果再次处理一个.mp4,它只是忽略而不复制。
  • @JanMüller 我没有看到逻辑。为什么处理完文件夹会被删除,又为什么不想再处理呢?
  • 它是种子文件的一种备份。种子将播种,但我可以移动或重命名文件或任何我想要的文件。 “删除”文件夹只是为了解释文件夹不会永远留在那个地方 - 可能会移动或删除......

标签: windows batch-file scripting


【解决方案1】:

Aacini写的answer不错,被我投了赞成票,但在某些情况下可能会导致MP4文件处理错误。

发生错误处理的条件有:

  1. *.mp4 文件存储在 FAT、FAT32 或 exFAT 上,而不是 NTFS 驱动器上。

    在 SD 卡和 USB 记忆棒上经常使用的 FAT 驱动器上,文件系统会根据文件分配表条目(通常最旧的第一个)返回匹配模式的文件,而不是像 NTFS 文件系统那样根据名称按字母顺序排序。

  2. 有些 MP4 文件的名称是其他名称较长的 MP4 文件的子字符串。

    例如,有一个文件 Test1.mp4 首先在 FAT32 驱动器上创建(文件分配表中的第一个),还有一个文件 Test.mp4 稍后创建,因此更新(文件分配表中的第二个)。

Aacini 编写的通常工作代码现在在 FAT32 驱动器上使用较旧的 Test1.mp4 和较新的 Test.mp4

  • 创建目录Test1,
  • Test1.mp4复制到目录Test1
  • Test1写入文本文件,
  • 跳过Test.mp4 的处理,因为字符串Test 已在文本文件中作为Test1 的子字符串找到。

可以进行以下增强以避免在这些情况下出现这种不需要的行为:

  1. 在命令 DIR 上使用参数 /ON 以获取按名称字母顺序排序的列表,就像在 NTFS 驱动器上一样。

  2. 确保不在文本文件中找到较长的文件/目录名称中的当前文件/目录名称。

并且文件/目录名称在 Windows 上不区分大小写,在使用选项 /I 搜索文本文件时也应考虑到这一点。

第一个解决方案还使用命令 FIND,它没有仅匹配整行的选项。因此,文件/目录名称与周围的 : 一起写入到文本文件中,并且还使用周围的冒号进行搜索。冒号不能作为文件或目录的名称,使其成为良好的开始/结束分隔符。

@echo off

if not exist FoldersCreated.txt cd . > FoldersCreated.txt

for /F "tokens=*" %%A in ('dir /A-D /B /ON *.mp4') do (
    %SystemRoot%\System32\find.exe /I ":%%~nA:" FoldersCreated.txt >NUL
    if errorlevel 1 (
        md "%%~nA"
        copy "%%~fA" "%%~nA\prefix_%%~nxA"
        echo :%%~nA:>>FoldersCreated.txt
    )
)

另一种解决方案是使用带有选项 /XFINDSTR,仅当搜索的字符串与整行匹配时才能获得肯定的结果。

@echo off

if not exist FoldersCreated.txt cd . > FoldersCreated.txt

for /F "tokens=*" %%A in ('dir /A-D /B /ON *.mp4') do (
    %SystemRoot%\System32\findstr.exe /I /L /M /X /C:"%%~nA" FoldersCreated.txt >NUL
    if errorlevel 1 (
        md "%%~nA"
        copy "%%~fA" "%%~nA\prefix_%%~nxA"
        echo %%~nA>>FoldersCreated.txt
    )
)

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • copy /?
  • dir /?
  • echo /?
  • find /?
  • findstr /?
  • for /?
  • if /?
  • md /?

注意:

必须注意echo %%~nA>>FoldersCreated.txt 行关于尾随空格的第二个解决方案。不应有尾随空格,否则 FINDSTR 在整行匹配中永远不会以 0 退出。

Aacini 发布的代码用作两种解决方案的模板,此行末尾有 1 个空格,即此行有 foldersCreated.txt空格

这个尾随空格被命令处理器解释为由命令 echo 输出的文本的一部分,因此由命令处理器执行:

echo Test1  1>>FoldersCreated.txt
echo Test  1>>FoldersCreated.txt

所以代码行末尾的空格被移动到文件名之后,因此也被写入文本文件。由于调用 FINDSTR 时搜索字符串中没有尾随空格,因此永远不会匹配整行。

在文件名前后使用双引号是没有解决办法的,即

echo %%~nA>>"FoldersCreated.txt"

同样使用双引号,命令处理器将尾随空格移动到文本末尾以通过命令 echo 输出。

使用也没有解决办法

>>FoldersCreated.txt echo %%~nA

必须避免在此行末尾留一个空格,因为命令处理器也将这一行执行为:

echo %%~nA 1>>FoldersCreated.txt 

因此,%%~nA 之后的任何空格都将成为 echo 输出的文本的一部分。

【讨论】:

    【解决方案2】:
    @echo off
    
    if not exist foldersCreated.txt cd . > foldersCreated.txt
    
    for /f "tokens=*" %%A in ('dir /b *.mp4') do (
       find "%%~nA" foldersCreated.txt > NUL
       if errorlevel 1 (
          md "%%~nA"
          copy "%%~fA" "%%~nA\prefix_%%~nxA"
          echo %%~nA>> foldersCreated.txt 
       )
    )
    

    【讨论】:

    • 不工作。该批次出现空...
    • @JanMüller - 脚本是否与您的 .mp4 文件位于同一目录中?
    • 是的。脚本在同一个文件夹中。
    • 您可以删除@echo off 行并从命令提示符窗口执行批处理文件:打开 cmd.exe,cd 到批处理文件所在的目录并输入其名称。屏幕上的输出会让您了解问题所在。
    • "foldersCreated.txt" 会产生某种语法错误。作为我德国人,我的操作系统给出了德国错误...:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    • 2020-02-11
    • 1970-01-01
    • 2019-07-09
    • 2015-05-09
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多