创建一个小批处理文件来管理文件
Creating a little Batch file to manage files
首先,对不起,如果我的英语不好,我来自西班牙。
我有一堆文件(数千个),分布在名为 INSTANCE 的文件夹内的一堆文件夹(几十个)中。只有 2 种文件类型(*.new、*.old)。并非每个文件夹中都有他们两个。我需要将每 100 个 *.new 文件移动到一个新文件夹中。如果存在任何 *.old 文件,请将它们全部移动到单独的文件夹中。我试过手动完成,但几个小时后我意识到这是一项主要任务,所以我想知道是否可以使用批处理文件来完成,一次所有文件夹或在每个文件夹中完成在 INSTANCE 文件夹中。
这听起来可能令人困惑,我首先展示一个现在的例子,然后展示它必须如何的第二个例子(而不是 100s,我展示 3s 的组)。
之前:
D:\[2016]\[01 JANUARY]\INSTANCE
│
├───aaa
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│ 13.old
│ 14.old
│
├───bbb
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│ 06.new
│ 07.new
│ 08.new
│ 13.old
│ 14.old
│ 15.old
│
├───ccc
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│
└───ddd
01.new
02.new
03.new
04.new
05.new
06.new
07.new
08.new
09.new
11.old
之后:
D:\[2016]\[01 JANUARY]\INSTANCE
│
├───aaa
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ ├───02
│ │ 04.new
│ │ 05.new
│ │
│ └───zz
│ 13.old
│ 14.old
│
├───bbb
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ ├───02
│ │ 04.new
│ │ 05.new
│ │ 06.new
│ │
│ ├───03
│ │ 07.new
│ │ 08.new
│ │
│ └───zz
│ 13.old
│ 14.old
│ 15.old
│
├───ccc
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ └───02
│ 04.new
│ 05.new
│
└───ddd
├───01
│ 01.new
│ 02.new
│ 03.new
│
├───02
│ 04.new
│ 05.new
│ 06.new
│
├───03
│ 07.new
│ 08.new
│ 09.new
│
└───zz
11.old
总结:
Look inside INSTANCE
for every folder inside
if any *.old file exists create a folder called ZZ and move there all of them
Then
create folder 01 and move 100 of the *.new files
create folder 02 and move the next 100
create folder 03 and move the next 100
...
Until all the files have been moved
在搜索如何做之前,因为我不是程序员,所以我想知道这是否可能并且对我来说值得学习曲线,因为这是一次性的事情。我读到有一些命令可以帮助完成某些任务(MD、IF EXIST、MOVE 等...),但如果我可以在一个批处理文件中完成所有这些任务就不行了。
提前致谢。
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o\instance"
SET /a filesperdir=3
PUSHD "%sourcedir%"
REM For each directory found in "sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /ad "*" '
) DO (
SET "dirname=%%a"
REM initialise subdirectory counter and file counter
SET /a subcount=0
SET /a filecount=filesperdir
REM scan for files "*.new"
FOR /f "delims=" %%c IN (
'dir /b /a-d ".\%%a\*.new" 2^>nul'
) DO (
REM name of file and move
SET "filename=%%c"
CALL :movenew
)
REM scan for files "*.old"
FOR /f "delims=" %%c IN (
'dir /b /a-d ".\%%a\*.old" 2^>nul'
) DO (
rem move to "zz"
MD ".\%%a\zz" >NUL 2>NUL
ECHO(MOVE ".\%%a\%%c" ".\%%a\zz\"
)
)
popd
GOTO :EOF
:movenew
REM one more file...
SET /a filecount +=1
REM filled this subdirectory?
if %filecount% gtr %filesperdir% SET /a subcount+=1&SET /a filecount=1
SET /a subnum=1000+subcount
REM try to make subdirectory
MD ".\%dirname%\%subnum:~-2%" >nul 2>nul
ECHO(MOVE ".\%dirname%\%filename%" ".\%dirname%\%subnum:~-2%\"
GOTO :eof
您需要更改 sourcedir
的设置以适合您的情况。
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。附加 >nul
以禁止报告消息(例如 1 file moved
)
我在线评论了这项工作是如何完成的。请注意,您需要使用 rem
而不是 ::
(通常用作更快输入的替代方法),因为这个技巧(::
代替 REM
)不起作用在代码块内(带括号的一系列语句)
粗略:对于找到的 reac 子目录,将子目录数设置为 0,将文件数设置为最大值。首先处理 .new
文件的子目录,然后处理 .old
。对于old
个文件,处理简单;只需将它们移动到子目录 zz
。对于 new
个文件,运行 子例程 movenew
.
:movenew
将 count-of-files-moved 加 1,如果结果大于允许的数量,则增加子目录计数并重置文件计数。
然后使用 subnum
计算子目录名称(字符串的最后 2 个字符)- 将 1000
添加到 subcount
可确保 subnum
始终为 4 位数字.
然后创建目录并移动文件。
请注意,如果目录已经存在,md
将创建一条错误消息。 2>nul
抑制此错误消息。 dir
命令中的 2^>nul
对于包含目标文件类型 none 的目录具有类似的目的。插入符号 ^
告诉处理器 >
是正在执行的命令的一部分,而不是 for
本身。
@echo off
setlocal EnableDelayedExpansion
rem Look inside INSTANCE
cd /D "D:\[2016]\[01 JANUARY]\INSTANCE"
rem for every folder...
for /D %%f in (*) do (
rem ... inside
cd "%%f"
rem if any *.old file exists...
if exist *.old (
rem ... create a folder called ZZ...
md ZZ
rem ... and move there all of them
move *.old ZZ
)
rem Then, create folders with two-digits and move 100 *.new files to each one
set /A twoDigits=100, files=-1
for %%a in (*.new) do (
set /A files+=1, filesMOD100=files%%100
rem Every 100 files, when the remainder of files/100 is zero...
if !filesMOD100! equ 0 (
rem ... create a new two-digits folder
set /A twoDigits+=1
md !twoDigits:~-2!
)
move "%%a" !twoDigits:~-2!
)
rem Go back to original folder -INSTANCE-
cd ..
)
首先,对不起,如果我的英语不好,我来自西班牙。
我有一堆文件(数千个),分布在名为 INSTANCE 的文件夹内的一堆文件夹(几十个)中。只有 2 种文件类型(*.new、*.old)。并非每个文件夹中都有他们两个。我需要将每 100 个 *.new 文件移动到一个新文件夹中。如果存在任何 *.old 文件,请将它们全部移动到单独的文件夹中。我试过手动完成,但几个小时后我意识到这是一项主要任务,所以我想知道是否可以使用批处理文件来完成,一次所有文件夹或在每个文件夹中完成在 INSTANCE 文件夹中。
这听起来可能令人困惑,我首先展示一个现在的例子,然后展示它必须如何的第二个例子(而不是 100s,我展示 3s 的组)。
之前:
D:\[2016]\[01 JANUARY]\INSTANCE
│
├───aaa
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│ 13.old
│ 14.old
│
├───bbb
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│ 06.new
│ 07.new
│ 08.new
│ 13.old
│ 14.old
│ 15.old
│
├───ccc
│ 01.new
│ 02.new
│ 03.new
│ 04.new
│ 05.new
│
└───ddd
01.new
02.new
03.new
04.new
05.new
06.new
07.new
08.new
09.new
11.old
之后:
D:\[2016]\[01 JANUARY]\INSTANCE
│
├───aaa
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ ├───02
│ │ 04.new
│ │ 05.new
│ │
│ └───zz
│ 13.old
│ 14.old
│
├───bbb
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ ├───02
│ │ 04.new
│ │ 05.new
│ │ 06.new
│ │
│ ├───03
│ │ 07.new
│ │ 08.new
│ │
│ └───zz
│ 13.old
│ 14.old
│ 15.old
│
├───ccc
│ ├───01
│ │ 01.new
│ │ 02.new
│ │ 03.new
│ │
│ └───02
│ 04.new
│ 05.new
│
└───ddd
├───01
│ 01.new
│ 02.new
│ 03.new
│
├───02
│ 04.new
│ 05.new
│ 06.new
│
├───03
│ 07.new
│ 08.new
│ 09.new
│
└───zz
11.old
总结:
Look inside INSTANCE
for every folder inside
if any *.old file exists create a folder called ZZ and move there all of them
Then
create folder 01 and move 100 of the *.new files
create folder 02 and move the next 100
create folder 03 and move the next 100
...
Until all the files have been moved
在搜索如何做之前,因为我不是程序员,所以我想知道这是否可能并且对我来说值得学习曲线,因为这是一次性的事情。我读到有一些命令可以帮助完成某些任务(MD、IF EXIST、MOVE 等...),但如果我可以在一个批处理文件中完成所有这些任务就不行了。
提前致谢。
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o\instance"
SET /a filesperdir=3
PUSHD "%sourcedir%"
REM For each directory found in "sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /ad "*" '
) DO (
SET "dirname=%%a"
REM initialise subdirectory counter and file counter
SET /a subcount=0
SET /a filecount=filesperdir
REM scan for files "*.new"
FOR /f "delims=" %%c IN (
'dir /b /a-d ".\%%a\*.new" 2^>nul'
) DO (
REM name of file and move
SET "filename=%%c"
CALL :movenew
)
REM scan for files "*.old"
FOR /f "delims=" %%c IN (
'dir /b /a-d ".\%%a\*.old" 2^>nul'
) DO (
rem move to "zz"
MD ".\%%a\zz" >NUL 2>NUL
ECHO(MOVE ".\%%a\%%c" ".\%%a\zz\"
)
)
popd
GOTO :EOF
:movenew
REM one more file...
SET /a filecount +=1
REM filled this subdirectory?
if %filecount% gtr %filesperdir% SET /a subcount+=1&SET /a filecount=1
SET /a subnum=1000+subcount
REM try to make subdirectory
MD ".\%dirname%\%subnum:~-2%" >nul 2>nul
ECHO(MOVE ".\%dirname%\%filename%" ".\%dirname%\%subnum:~-2%\"
GOTO :eof
您需要更改 sourcedir
的设置以适合您的情况。
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。附加 >nul
以禁止报告消息(例如 1 file moved
)
我在线评论了这项工作是如何完成的。请注意,您需要使用 rem
而不是 ::
(通常用作更快输入的替代方法),因为这个技巧(::
代替 REM
)不起作用在代码块内(带括号的一系列语句)
粗略:对于找到的 reac 子目录,将子目录数设置为 0,将文件数设置为最大值。首先处理 .new
文件的子目录,然后处理 .old
。对于old
个文件,处理简单;只需将它们移动到子目录 zz
。对于 new
个文件,运行 子例程 movenew
.
:movenew
将 count-of-files-moved 加 1,如果结果大于允许的数量,则增加子目录计数并重置文件计数。
然后使用 subnum
计算子目录名称(字符串的最后 2 个字符)- 将 1000
添加到 subcount
可确保 subnum
始终为 4 位数字.
然后创建目录并移动文件。
请注意,如果目录已经存在,md
将创建一条错误消息。 2>nul
抑制此错误消息。 dir
命令中的 2^>nul
对于包含目标文件类型 none 的目录具有类似的目的。插入符号 ^
告诉处理器 >
是正在执行的命令的一部分,而不是 for
本身。
@echo off
setlocal EnableDelayedExpansion
rem Look inside INSTANCE
cd /D "D:\[2016]\[01 JANUARY]\INSTANCE"
rem for every folder...
for /D %%f in (*) do (
rem ... inside
cd "%%f"
rem if any *.old file exists...
if exist *.old (
rem ... create a folder called ZZ...
md ZZ
rem ... and move there all of them
move *.old ZZ
)
rem Then, create folders with two-digits and move 100 *.new files to each one
set /A twoDigits=100, files=-1
for %%a in (*.new) do (
set /A files+=1, filesMOD100=files%%100
rem Every 100 files, when the remainder of files/100 is zero...
if !filesMOD100! equ 0 (
rem ... create a new two-digits folder
set /A twoDigits+=1
md !twoDigits:~-2!
)
move "%%a" !twoDigits:~-2!
)
rem Go back to original folder -INSTANCE-
cd ..
)