1

Тема: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Помогите решить задачу.
Необходимо периодически выполнять сортировку накопленных в папке FOLDER-1 и во всех её подпапках файлов, перенося их в папку FOLDER-2 разнеся по подпапкам. Все подпапки в FOLDER-2 имеют имя длинной в два символа. Первые два символа имени каждого файла из подпапок FOLDER-1 определяют в какую именно подпапку FOLDER-2 он должен быть помещен.

2 (изменено: Flasher, 2016-02-26 13:14:17)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

+ vbs пойдёт?:
IPath = "C:\FOLDER-1"
TPath = "D:\FOLDER-2"
Filt  = "*.fil;*.txt;*.lst"

Set FSO   = CreateObject("Scripting.FilesystemObject")
Set Shell = CreateObject("Shell.Application")
If Not FSO.FolderExists(TPath) Then FSO.CreateFolder TPath
FFolder IPath

Sub FFolder(Folder)
	Set Items = Shell.NameSpace(Folder).Items
	Items.Filter 73920, Filt
	For Each F In Items
		Trg = FSO.BuildPath(TPath, UCase(Left(F.Name, 2)))
		If Not FSO.FolderExists(Trg) Then FSO.CreateFolder Trg 
		Shell.NameSpace(Trg).MoveHere F, 280
	Next : Items.Filter 73888, "*"
	For Each F In Items : FFolder F.Path : Next
End Sub

3

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

@echo off

set "src=FOLDER-1"
set "dest=FOLDER-2"

2>nul cmd/v/c "for /f %%i in ('dir/a-d/b/s "%src%"') do @set "x=%%~ni"& set "y=%dest%\!x:~,2!"& md "!y!"& move/y "%%i" "!y!""

exit/b

4

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

YuryСпасибо! Работает.

5 (изменено: Abashin, 2016-02-26 08:07:10)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Yury
Поторопился. Не работает как надо.
Если папки и файлы в FOLDER-1 имеют короткие имена - всё работает хорошо.

T:\FOLDER-1\78AA5489.iil
T:\FOLDER-1\F077-A1D.fil
T:\FOLDER-1\1\F077-A1D.fil
T:\FOLDER-1\1\11\A0AA5489.fil
T:\FOLDER-1\2\A83DDC49.fil
T:\FOLDER-1\2\FA77-A1D.iil

результат

T:\FOLDER-2\78\78AA5489.iil
T:\FOLDER-2\A0\A0AA5489.fil
T:\FOLDER-2\A8\A83DDC49.fil
T:\FOLDER-2\F0\F077-A1D.fil
T:\FOLDER-2\FA\FA77-A1D.iil

Если встречаются длинные имена - возникают проблемы.

T:\FOLDER-1\78AA5489.iil
T:\FOLDER-1\F077-A1D F077-A1D.fil
T:\FOLDER-1\1 папка с файлами\F077-A1D F077-A1D.fil
T:\FOLDER-1\1 папка с файлами\11 папка с файлами\A0AA5489 A0AA5489.fil
T:\FOLDER-1\2 папка с файлами\A83DDC49.fil
T:\FOLDER-1\2 папка с файлами\FA77-A1D.iil

результат

T:\FOLDER-2\1\
T:\FOLDER-2\2\
T:\FOLDER-2\78\78AA5489.iil
T:\FOLDER-2\F0\

6

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin пишет:

Если встречаются длинные имена - возникают проблемы.



Уточню, не длинные имена, а пробелы в полном пути. И на старуху бывает... Забыл кое-что...

@echo off

set "src=FOLDER-1"
set "dest=FOLDER-2"

2>nul cmd/v/c "for /f "delims=" %%i in ('dir/a-d/b/s "%src%"') do @set "x=%%~ni"& set "y=%dest%\!x:~,2!"& md "!y!"& move/y "%%i" "!y!""

exit/b

7

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
А мой вариант с автопереименованием при совпадении имён чем не устроил?

8

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Извините, Flasher. Я "лошара" не увидел вашего варианта, поскольку не догадался развернуть плюсик, за которым был скрыт код...
А куда его нужно вставить чтоб проверить?

9

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Там же написано - vbs. Это расширение. Только пути нужно верные указать.

10

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Yury, огромное спасибо! Всё работает.
Маленький нюанс изредка встречается (возможно он не устранимый). Иногда имена папки или файла в FOLDER-1 содержат символы не из ACII кодировки. Такие папки/файлы не обрабатываются. Поскольку это редко - думаю можно руками отсортировать.

11

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Используйте мой скрипт, там нет и этой проблемы.

12

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher
Проверил - папки в FOLDER-2 создаёт, но файлы не переносит.

13

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Пардон, поправил.

14 (изменено: Abashin, 2016-02-26 13:04:46)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher, спасибо - работает!
В варианте дла bat-файла я добавлял расширение обрабатываемых файлов из FOLDER-1. Поскольку для файлов с разными расширениями разные папки назначения.
А в вашем коде я ничего не понимаю и не знаю куда там можно вставить шаблон, например *.fil

15

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Добавил указание фильтра в 3 строке.

16 (изменено: Abashin, 2016-02-26 13:55:04)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher
Спасибо

Если нужно чтобы файлы с разными (заранее известными) расширениями попадали в разные папки так изменить ваш код будет корректно?

+ открыть спойлер

IPath = "T:\FOLDER-1"
TPath = "T:\FOLDER-2\FIL"
Filt  = "*.fil"

Set FSO   = CreateObject("Scripting.FilesystemObject")
Set Shell = CreateObject("Shell.Application")
If Not FSO.FolderExists(TPath) Then FSO.CreateFolder TPath
FFolder IPath

Sub FFolder(Folder)
Set Items = Shell.NameSpace(Folder).Items
Items.Filter 73920, Filt
For Each F In Items
Trg = FSO.BuildPath(TPath, UCase(Left(F.Name, 2)))
If Not FSO.FolderExists(Trg) Then FSO.CreateFolder Trg
Shell.NameSpace(Trg).MoveHere F, 280
Next : Items.Filter 73888, "*"
For Each F In Items : FFolder F.Path : Next
End Sub

TPath = "T:\FOLDER-2\TXT"
Filt  = "*.txt"

Set FSO   = CreateObject("Scripting.FilesystemObject")
Set Shell = CreateObject("Shell.Application")
If Not FSO.FolderExists(TPath) Then FSO.CreateFolder TPath
FFolder IPath

Sub FFolder(Folder)
Set Items = Shell.NameSpace(Folder).Items
Items.Filter 73920, Filt
For Each F In Items
Trg = FSO.BuildPath(TPath, UCase(Left(F.Name, 2)))
If Not FSO.FolderExists(Trg) Then FSO.CreateFolder Trg
Shell.NameSpace(Trg).MoveHere F, 280
Next : Items.Filter 73888, "*"
For Each F In Items : FFolder F.Path : Next
End Sub

TPath = "T:\FOLDER-2\LST"
Filt  = "*.lst"

Set FSO   = CreateObject("Scripting.FilesystemObject")
Set Shell = CreateObject("Shell.Application")
If Not FSO.FolderExists(TPath) Then FSO.CreateFolder TPath
FFolder IPath

Sub FFolder(Folder)
Set Items = Shell.NameSpace(Folder).Items
Items.Filter 73920, Filt
For Each F In Items
Trg = FSO.BuildPath(TPath, UCase(Left(F.Name, 2)))
If Not FSO.FolderExists(Trg) Then FSO.CreateFolder Trg
Shell.NameSpace(Trg).MoveHere F, 280
Next : Items.Filter 73888, "*"
For Each F In Items : FFolder F.Path : Next
End Sub

17 (изменено: Flasher, 2016-02-29 13:33:25)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin

+ Если подпапки первого уровня = расширения файлов, то лучше так:
IPath = "T:\FOLDER-1"
TPath = "T:\FOLDER-2"
Filt  = "*.fil;*.txt;*.lst"

Set Shell = CreateObject("Shell.Application")
Set FSO   = CreateObject("Scripting.FilesystemObject")
Set OutDisk = Shell.NameSpace(FSO.GetDriveName(TPath))
FFolder IPath

Sub FFolder(Folder)
  Set Items = Shell.NameSpace(Folder).Items
  Items.Filter 73920, Filt
  For Each F In Items
	Ext = FSO.GetExtensionName(F.Path)
    Set Elems = Shell.NameSpace(Folder).Items
    Elems.Filter 73920, Left(F.Name, 2) & "*." & Ext
    Trg = FSO.BuildPath(TPath, UCase(Ext)) & "\" & UCase(Left(F.Name, 2))
    If Not FSO.FolderExists(Trg) Then OutDisk.NewFolder(Mid(Trg, 4))
    Shell.NameSpace(Trg).MoveHere Elems, 280
	Set Items = Shell.NameSpace(Folder).Items
    Items.Filter 73920, Filt
  Next : Items.Filter 73888, "*"
  For Each F In Items : FFolder F.Path : Next
End Sub
+ Если эти подпапки  произвольно названные, то так:
IPath = "T:\FOLDER-1"
TPath = "T:\FOLDER-2"

Set ShA = CreateObject("Shell.Application")
Set Dic = CreateObject("Scripting.Dictionary")
Set FSO = CreateObject("Scripting.FilesystemObject")
Set OutDisk = ShA.NameSpace(FSO.GetDriveName(TPath))

'** Тут прописываем соотв. пути и маски: ***
Dic.Add FSO.BuildPath(TPath, "FIL"), "*.fil"
Dic.Add FSO.BuildPath(TPath, "TXT"), "*.txt"
Dic.Add FSO.BuildPath(TPath, "LST"), "*.lst"
'*******************************************
FFolder IPath

Function FFolder(Folder)
  Set Items = ShA.NameSpace(Folder).Items
  For Each TPath In Dic.Keys
    Filt = Dic.Item(TPath)
    Items.Filter 73920, Filt
    For Each F In Items
      F = FSO.GetBaseName(F)
      Set Elems = ShA.NameSpace(Folder).Items
      Elems.Filter 73920, Left(F, 2) & Filt
      Trg = FSO.BuildPath(TPath, UCase(Left(F, 2)))
      If Not FSO.FolderExists(Trg) Then OutDisk.NewFolder(Mid(Trg, 4))
      ShA.NameSpace(Trg).MoveHere Elems, 280
	  Set Items = ShA.NameSpace(Folder).Items
      Items.Filter 73920, Filt
    Next
  Next : Items.Filter 73888, "*"
  For Each F In Items : FFolder F.Path : Next
End Function

18

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher
Спасибо

19

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Пож-та. Во втором скрипте пару имён исправил.

20

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher
Еще вопрос. Что нужно изменить в скрипте, чтобы происходила перезапись существующих в конечной папке файлов, а не запись с новым именем: Копия filename.ext?

21

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
272 вместо 280. Но смысл? Ведь в разных каталогах могут оказаться одноимённые файлы, которые в итоге перезапишут друг друга, и файлов будет перенесено меньше положенного.
И, кстати, копия должна быть после базового имени, а не перед.

22

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher пишет:

272 вместо 280.

А какие бывают ещё варианты? Подскажите где прочитать об значениях этого параметра?

23

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
На русском у нас. Хотя с полным перечнем лучше на msdn.

24 (изменено: Abashin, 2016-02-28 10:28:32)

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher пишет:

На русском у нас. Хотя с полным перечнем лучше на msdn.

Спасибо!
Разобрался. Не смог только на msdn найти полный перечень параметров для Filter. А на вашем сайте перечислены только три варианта.


Flasher пишет:
+ Если подпапки первого уровня = расширения файлов, то лучше так:
IPath = "T:\FOLDER-1"
TPath = "T:\FOLDER-2"
Filt  = "*.fil;*.txt;*.lst"

Set Shell = CreateObject("Shell.Application")
Set FSO   = CreateObject("Scripting.FilesystemObject")
Set OutDisk = Shell.NameSpace(FSO.GetDriveName(TPath))
FFolder IPath

Sub FFolder(Folder)
  Set Items = Shell.NameSpace(Folder).Items
  Items.Filter 73920, Filt
  For Each F In Items
	Ext = FSO.GetExtensionName(F.Path)
    Set Elems = ShA.NameSpace(Folder).Items
    Elems.Filter 73920, Left(F.Name, 2) & "*." & Ext
    Trg = FSO.BuildPath(TPath, UCase(Ext)) & "\" & UCase(Left(F.Name, 2))
    If Not FSO.FolderExists(Trg) Then OutDisk.NewFolder(Mid(Trg, 4))
    ShA.NameSpace(Trg).MoveHere Elems, 280
    Items.Filter 73920, Filt
  Next : Items.Filter 73888, "*"
  For Each F In Items : FFolder F.Path : Next
End Sub

Этот вариант оказывается не работает.
https://drive.google.com/file/d/0B_3VWn … sp=sharing

+ Если эти подпапки  произвольно названные, то так:
IPath = "T:\FOLDER-1"
TPath = "T:\FOLDER-2"

Set ShA = CreateObject("Shell.Application")
Set Dic = CreateObject("Scripting.Dictionary")
Set FSO = CreateObject("Scripting.FilesystemObject")
Set OutDisk = ShA.NameSpace(FSO.GetDriveName(TPath))

'** Тут прописываем соотв. пути и маски: ***
Dic.Add FSO.BuildPath(TPath, "FIL"), "*.fil"
Dic.Add FSO.BuildPath(TPath, "TXT"), "*.txt"
Dic.Add FSO.BuildPath(TPath, "LST"), "*.lst"
'*******************************************
FFolder IPath

Function FFolder(Folder)
  Set Items = ShA.NameSpace(Folder).Items
  For Each TPath In Dic.Keys
    Filt = Dic.Item(TPath)
    Items.Filter 73920, Filt
    For Each F In Items
      Set Elems = ShA.NameSpace(Folder).Items
      Elems.Filter 73920, Left(F.Name, 2) & Filt
      Trg = FSO.BuildPath(TPath, UCase(Left(F.Name, 2)))
      If Not FSO.FolderExists(Trg) Then OutDisk.NewFolder(Mid(Trg, 4))
      ShA.NameSpace(Trg).MoveHere Elems, 280
      Items.Filter 73920, Filt
    Next
  Next : Items.Filter 73888, "*"
  For Each F In Items : FFolder F.Path : Next
End Function

Этот вариант работает в WinXP нормально, а в Win7 только создаёт структуру папок в FOLDER-2 без переноса файлов (ограничения безопасности?).

25

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Не нужно цитировать посты с кодами, достаточно написать про первый и второй вариант.
Первый поправил. Второй проверил на Win7 x86, никаких проблем. Возможно, фильтрация указана неверно.
Внёс мелкую коррекцию, чтобы файлы с односимвольным базовым именем тоже переносились.

Что касаемо флагов Filter, то список тут. В vbs вместо 0x пишется &H либо числами, как у меня (как правило этих флагов достаточно).

26

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Flasher
Где-то в логике скрипта (первого и второго варианта) серьёзная ошибка.
Скрипт завершает работу перенеся не все файлы соответствующие заданным шаблонам. Если повторно запустить скрипт пропущенные файлы переносятся. Все или требуется третий и четвертый запуск не установлено пока. В модельной ситуации (https://drive.google.com/file/d/0B_3VWn … sp=sharing, первый вариант пропускает 6 файлов, второй 1 файл. Всегда одни и те же файлы.

27

Re: CMD/BAT: перенос файлов из каталога и его подкаталогов с сортировкой

Abashin
Ага, точно. Добавил важную строку.