创建一个小批处理文件来管理文件

时间:2016-09-27 21:18:21

标签: batch-file cmd command

首先,对不起,如果我的英语不好,我来自西班牙。

我有一堆文件(数千个),在一个名为INSTANCE的文件夹中的一堆文件夹(数十个)中传播。只有2种文件类型(* .new,* .old)。不是每个文件夹都是他们两个。我需要将每个* .new文件移动到每个100个文件夹的新文件夹中。如果存在任何* .old文件,则将它们全部移动到单独的文件夹中。我已尝试手工完成,但经过一段时间后,我意识到这是一项重大任务,所以我想知道是否可以使用批处理文件执行此操作,或者是所有文件夹立即或在INSTANCE文件夹内的每个文件夹中执行此操作。

也许这听起来很混乱,我首先展示一个例子,现在是第二个例子,它是如何形成的(而不是100个我显示的是3个群组)。

之前:

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等等),但是如果我可以在一个批处理文件中完成所有任务,那就不行了。

提前致谢。

2 个答案:

答案 0 :(得分:2)

@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在您确认命令正确后,将ECHO(MOVE更改为MOVE以实际移动文件。附加>nul以取消报告消息(例如1 file moved

我已经在线评论了这项工作是如何完成的。请注意,您需要使用rem而不是::(通常用作更快速的替代方案),因为此技巧(::代替REM)不起作用在acode-block(带括号的系列语句)中

粗略轮廓:对于找到的reac子目录,将subdir count设置为0,将filecount设置为max。首先处理.new个文件的子目录,然后处理.old。对于old文件,处理很简单;只需将它们移动到子目录zz即可。对于new文件,请运行子例程movenew

:movenew在移动的文件计数中加1,如果结果大于允许的数量,则递增子目录计数并重置文件计数。

然后使用subnum计算子目录名称(字符串的最后2个字符) - 将1000添加到subcount可确保subnum始终为4位数。 然后创建目录并移动文件。

请注意,如果目录已存在,md将会创建一条错误消息。 2>nul会禁止显示此错误消息。 2^>nul命令中的dir对于不包含目标文件类型的目录具有类似的用途。插入符^告诉处理器>是正在执行的命令的一部分,而不是for本身。

答案 1 :(得分:2)

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

)