如何通过子目录循环批处理文件

时间:2017-06-22 04:57:58

标签: batch-file

某些背景: 我从大约100张以AFSM-DDMMYY_doe-john.jpg格式命名的jpg图像开始,然后根据它们的名称将其分类到文件夹中,只使用以下脚本:

foldercreator.bat

@echo off &setlocal
for /f "delims=" %%i in ('dir /b /a-d *.jpg') do (
    set "filename1=%%~i"
    setlocal enabledelayedexpansion
    set "folder1=!filename1:~12,-4!"
    mkdir "!folder1!" 2>nul
    move "!filename1!" "!folder1!" >nul
)

然后删除文件名的_last-first部分,使图像以AFSM-DDMMYY.jpg的格式结束。这是使用下面的脚本完成的:

nameremover.bat

@echo off &setlocal
for /f "delims=" %%i in ('dir /b /a *.jpg') do (
    set "filename1=%%~i"
    setlocal enabledelayedexpansion
    set "name1=!filename1:~0,11!"
    ren "!filename1!" "!name1!.jpg"
)

生成的文件夹最终被命名为doe-john,其中包含AFSM-DDMMYY.jpg图像。为此,这些文件夹都在一个公共文件夹中。这很好但我希望能够从公共文件夹中运行nameremover.bat,以便它在所有doe-john文件夹中运行,而不是我必须将它移动到每个文件夹,然后在那里单独运行它。提前谢谢。

1 个答案:

答案 0 :(得分:0)

简单的方法是创建一个包含批处理文件的目录 - 常用名称为batchbelfry,并在path变量中包含该目录名。这样,无论当前目录如何,都可以执行目录中的任何批处理文件。

哦 - 顺便说一下:为什么不用你的

move "!filename1!" "!folder1!\!filename1:~0,11!!filename1:~-4!" >nul

在你的第一批?

当您指定可执行文件的路径(例如c:\some\directory\executable.exe)时,那将是将要执行的文件。但是,如果省略该目录并只执行executable.exe,则会尝试在当前目录中找到该文件。如果失败,则检查环境变量path,并运行path上找到的第一个匹配的可执行文件。

因此,如果您修改path以包含c:\batch等目录,那么如果executablename.exe中存在c:\batch,那么任何运行可执行文件的尝试都会运行它。目录

可执行文件有很多种,其中最重要的是.bat.cmd.exe,可以使用 base 名称调用,因此执行fred会在fred.bat(当前目录)和fred.cmd(包含环境变量)中找到fred.exe.%path%以分号分隔的目录名列表)

可以使用Windows 更改路径,但像path editor(Google it)这样的第三方实用程序可以轻松实现。

所以 - 您需要做的就是建立一个包含批量文件的目录(您已使用mkdir命令在已发布的批次中执行此操作(尽管使用{更常见] {1}}这是md的同义词))然后将批处理移动到该目录,并且无论当前目录位于何处,都可以使用其基本名称运行批处理。

实际上,我在那里存储了多个批次 - 我也将它用于我的所有实用程序mkdir - 例如.exe

分析您的代码,

  

@echo off& setlocal

sed级联这两个命令。 &转向命令回显@echo offoff建立一个本地环境,确保对环境的任何更改(创建或删除的变量等)在最后恢复到原始状态批次。请注意,这不会恢复添加/删除/更改/移动的文件 - 只是环境变量。

  

for / f" delims =" %% i in(' dir / b / a-d * .jpg')do(

执行setlocal命令查找所有dir个文件;仅限名称,没有目录名称。将此列表放入内存,就像它是一个文件一样。 "读"列表,逐行并依次将每行的内容分配给.jpg

  

设置" filename1 = %% ~i"

将环境变量%%i设置为filename1的内容= %%i行的内容。

  

setlocal enabledelayedexpansion

NEST是一个新的本地环境,但是这个环境已调用dir,因此delayedexpansion表示" !var!的当前值,而var表示&#34 ;遇到 %var% **时var 的值**

  

set" folder1 =!filename1:~12,-4!"

for设置为folder1当前值,从第13个字符开始(计数从&#34开始;字符0和#34;)到第4个字符结束。

  

mkdir"!folder1!" 2 - ; NUL

制作该目录,抑制和错误消息(例如'它已经存在')

  

move"!filename1!" "!文件夹1&#34!; > NUL

将文件移动到新目录。自filename1移动"folder1!" is a directory, the file will be moved into that directory. If it didn't exist, the"!folder1!"`

  

... would move the file to a **file** named在几行前的code block之后由(开始结束。

<强>注意

do建立嵌套本地环境。这些是有限的。您应该在setlocal命令之后放置endlocal命令以结束本地环境,因此您的代码应该为每个处理的文件创建和删除本地环境。

因此,如果move被我提倡的move取代,则更改将意味着移动的目标是[{1}}中的目标目录\前12个字符move + folder1]

中的最后4个字符

可以避免filename1进程。

IOW,

filename1

应该进行处理,而无需执行&#39; nameremover&#39;步。进行nameremover更改后,将其放在@echo off &setlocal for /f "delims=" %%i in ('dir /b /a-d *.jpg') do ( set "filename1=%%~i" setlocal enabledelayedexpansion set "folder1=!filename1:~12,-4!" mkdir "!folder1!" 2>nul move "!filename1!" "!folder1!\!filename1:~0,11!!filename1:~-4!" >nul ENDLOCAL ) 目录中,无论您在系统中的哪个位置,都可以直接从提示符运行代码,包括登录到其他驱动器。

要建立菜单,传统方法是:

\batch

path在提示符下将提供有关:again cls echo 1. do thing 1 echo 2. do thing 2 echo 3. do thing 3 echo q quit choice /c 123q /m please choose... if errorlevel 4 goto :eof if errorlevel 3 call batch3&goto again if errorlevel 2 call batch2&goto again if errorlevel 1 call batch1&goto again goto again 工作原理的指南。

choice /?根据其中的字符位置设置 密钥的choice字符串已激活。

如果errorlevel为n 或大于n ,则/c为真 代码必须以反向顺序构造。

要执行的代码可能会改变if errorlevel n的值。 因此,在执行子公司后需要errorlevel 批处理以确保从errorlevel返回,比如说没有被解释 剩下的goto陈述。