Создание списка файлов выборочно по расширениям

Обсуждение вопросов автоматизации Total Commander с помощью сторонних программ и скриптовых технологий.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Tol!k
Для порядка вещей, добей, пож., тему кнопкой с абсолютными путями. :wink:
Список кидать в противоположную панель. И желательно списки из разных папок отделять пустыми строками.
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Jonmey писал(а):И что тут непонятного?
В данном случае всё понятно, но ещё раз прошу обратить внимание, что обсуждение твоей задачи в теме "Создание списка файлов выборочно по расширениям" по сути является оффтопом.
Во избежание ненужных дискуссий, решение твоей задачи в виде vbs-скрипта:

Код: Выделить всё

'=====================================================================
' Создание списка файлов относительно текущей папки

' Параметры:
' {исходный файл-список|папка} {требуемый файл-список}
' Если первым параметром передан путь к папке, то
'   обрабатываеются только эта папка, причём она считается текущей.
' Если для параметра {требуемый файл-список} указан не полный путь, то
'   файл-список создаётся в текущей папке.

' Примеры параметров при вызове из TC:
' %L "C:\Путь\Файл-список.txt"
' %P%N "Файл-список.txt"
'=====================================================================

Dim FSO, FolderMode, FF, F, List, CurrentFolder, TargetList, LenCF
Set FSO = CreateObject("Scripting.FileSystemObject")

FF         = WScript.Arguments(0)
TargetList = WScript.Arguments(1)
FolderMode = FSO.FolderExists(FF)

If FolderMode Then
  CurrentFolder = FF
Else
  CurrentFolder = CreateObject("WScript.Shell").CurrentDirectory
End If
If Right(CurrentFolder, 1) <> "" Then CurrentFolder = CurrentFolder & ""
LenCF = Len(CurrentFolder)

If InStr(TargetList, ":") = 0 Then TargetList = CurrentFolder & TargetList

If FolderMode Then
  List = Process(CurrentFolder)
Else
  With FSO.OpenTextFile(FF, 1)
    Do While Not .AtEndOfStream
      F    = .ReadLine
      List = List & Process(F)
    Loop
  End With
End If

FSO.CreateTextFile(TargetList, True, True).Write List

Set FSO = Nothing
Wscript.Quit()

Function Process(pPath)
  Dim lF
  If FSO.FileExists(pPath) Then Process = Cut(pPath)
  If FSO.FolderExists(pPath) Then
    For Each lF in FSO.GetFolder(pPath).Files
      Process = Process & Cut(lF) & vbNewLine
    Next
    For Each lF in FSO.GetFolder(pPath).SubFolders
      Process = Process & Process(lF)
    Next
  End If
End Function

Function Cut(pPath)
  Cut = Mid(pPath, LenCF + 1)
End Function
Внимание! У кнопки\команды параметр "Путь запуска" должен быть пустой.
Последний раз редактировалось Batya Вт янв 25, 2011 12:30, всего редактировалось 1 раз.
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
dude
Сообщения: 11
Зарегистрирован: Пт янв 21, 2011 06:02

Сообщение dude »

Признаться, не ожидал такой быстрой и продуктивной реакции! Спасибо всем, кто отозвался!
Batya писал(а):Если выделенно несколько каталогов, то списков должно быть несколько (по одному в каждом выделенном каталоге)?
Я имел в виду создание списка файлов по расширению для одного выделенного каталога с подкаталогами в один текст. файл. Сама идея создания отдельных списков для каждого из каталогов (с подкаталогами) интересна, но часто ли подобное нужно? И решается ведь просто созданием списка файлов для каталога следующего уровня все по той же изначальной схеме.
Batya писал(а):Не понял, в каком виде должен быть список.
Варианты:
2.

Код: Выделить всё

Файл1.avi
Подкаталог\Файл2.avi
Вариант 2. Ниже поясню чуть подробнее.

Tol!k, то что Вы предложили, все 3 варианта скрипта — уже отличные рабочие инструменты, спасибо! Но есть пара пожеланий во имя идеала ;)
Проиллюстрирую без лишних слов. Хотелось бы видеть список приблизительно такого вида (опять же формат видео-файлов выбран лишь как образец).

Код: Выделить всё

VIDEO
_COMEDY
  Автостопом по Галактикам.mov
  4 комнаты.avi
и т.д.

_DRAMA
  Вальсирующие.mp4
  Зелёная миля.avi
--MAYA DEREN
   Divine Horsemen — The Living Gods of Haiti.mkv
   Meshes of the Afternoon.mkv
  Зелёная миля.avi
  Рестлер.avi
и т.д.

_ANIMATION
  Mэри и Макс.flv
  Beltesassar's Short Animation Festival.mp4
--НОРШТЕЙН
   Сказка сказок.mov
   Ёжик в тумане.mov
   Шинель.mov
  Трио из Бельвилля.avi
и т.д.
Здесь видно что подкаталоги отделяются "--", или при бОльших вложениях бОльшим числом "-". Сами файлы пробелами. Каталоги с подкаталогами определяются в верхнем регистре, файлы — как есть.
Мне кажется, даже такое простейшее форматирование текста значительно облегчило бы его восприятие.
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Batya писал(а):Создание списка файлов относительно текущей папки
Я, конечно, извиняюсь, но разве с его задачей скрипт не должен называться "... относительно выделенных папок" ?
Последний раз редактировалось Flasher Пн янв 24, 2011 17:38, всего редактировалось 1 раз.
Jonmey
Сообщения: 59
Зарегистрирован: Пн сен 27, 2010 14:01

Сообщение Jonmey »

dude
Ваша задача, как мне думается, проще решается с помощью архиваторного плагина Catalog Maker. Настроив его соответствующим образом, и можно получать списки, например, такого вида:

Код: Выделить всё

MOVIE\
   MOVIE\ACTION\
      Film 01.mkv
      Film 02.avi
      Film 03.mkv
   MOVIE\ANIME\
      Film 04.avi
      Film 05.mkv
      Film 06.mpg
   MOVIE\COMEDY\
      Film 07.mkv
      Film 08.avi
      Film 09.mp4
   MOVIE\DRAMA\
      Film 10.avi
      Film 11.mkv
      Film 12.wmv

total files 12
Flasher
Flasher писал(а):Для порядка вещей, добей, пож., тему кнопкой с абсолютными путями.
Список кидать в противоположную панель. И желательно списки из разных папок отделять пустыми строками.
Вроде работает (список файлов выбранных папок с полными путями с выводом на противоположную панель в юникоде):

Код: Выделить всё

TOTALCMD#BAR#DATA 
%comspec% /u /c cd.>list.txt& 
for /f "delims=" %%d in ('type %WL') do (for /f "delims=" %%f in ('dir/b/s/on/a-d "%%d"') do (set "$f=%%f"&call echo %%$f:/=%%>>"%Tlist.txt")) 
%commander_path%\totalcmd.exe,24 
выделенное > список с путями 

1 
-1
Пустые строки не вставляет.
Последний раз редактировалось Jonmey Вт янв 25, 2011 02:56, всего редактировалось 5 раз.
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Flasher писал(а):Я, конечно, извиняюсь, но разве с его задачей скрипт не должен называться "... относительно выделенных папок" ?
Не обязательно выделять несколько папок. Работает и с одной папкой. Но, на мой взгляд, ключевым является то, что путь файла в списке отражается относительным.
dude писал(а):Я имел в виду создание списка файлов по расширению для одного выделенного каталога с подкаталогами в один текст. файл.
А я спрашиваю, что делать, если выделено несколько.
Пока не совсем въехал, когда вставлять перед новой папкой пустые строки, а когда - нет. Попробуй пока такой вариант:

Код: Выделить всё

'=====================================================================
' Создание списка файлов относительно текущей папки
'   для заданных расширений файлов

' Параметры:
' {исходный файл-список|папка} {требуемый файл-список} {расширения}
' Если первым параметром передан путь к папке, то
'   обрабатываеются только эта папка, причём она считается текущей.
' Если для параметра {требуемый файл-список} указан не полный путь, то
'   файл-список создаётся в текущей папке.
' Список расширений чередуется символом ","

' Примеры параметров при вызове из TC:
' %L "C:\Путь\Файл-список.txt" "avi,mov,mkv"
' %P%N "Файл-список.txt" "jpeg,bmp"
'=====================================================================

Dim FSO, FolderMode, FF, F, List, CurrentFolder, TargetList, LenCF, EXT, E
Set FSO = CreateObject("Scripting.FileSystemObject")
Set EXT = CreateObject("Scripting.Dictionary")

FF         = WScript.Arguments(0)
TargetList = WScript.Arguments(1)
FolderMode = FSO.FolderExists(FF)
For Each E In Split(WScript.Arguments(2), ",")
  EXT.Add LCase(Trim(E)), ""
Next

If FolderMode Then
  CurrentFolder = FF
Else
  CurrentFolder = CreateObject("WScript.Shell").CurrentDirectory
End If
If Right(CurrentFolder, 1) <> "" Then CurrentFolder = CurrentFolder & ""
LenCF = Len(CurrentFolder)

If InStr(TargetList, ":") = 0 Then TargetList = CurrentFolder & TargetList

If FolderMode Then
  List = Process(CurrentFolder, 0)
Else
  With FSO.OpenTextFile(FF, 1)
    Do While Not .AtEndOfStream
      F    = .ReadLine
      List = List & Process(F, 0)
    Loop
  End With
End If

FSO.CreateTextFile(TargetList, True, True).Write List

Set FSO = Nothing
Wscript.Quit()

Function Process(pPath, pLevel)
  Dim lF
  If FSO.FileExists(pPath) Then
    If EXT.Exists(LCase(FSO.GetExtensionName(pPath))) Then Process = Space((pLevel + 1) * 2) & Cut(pPath)
  End If
  If FSO.FolderExists(pPath) Then
    Process = Process & String(pLevel * 2, "-") & UCase(FSO.GetFileName(pPath)) & vbNewLine
    For Each lF in FSO.GetFolder(pPath).Files
      If EXT.Exists(LCase(FSO.GetExtensionName(lF))) Then Process = Process & Space((pLevel + 1) * 2) & Cut(lF) & vbNewLine
    Next
    For Each lF in FSO.GetFolder(pPath).SubFolders
      Process = Process & Process(lF, pLevel + 1)
    Next
  End If
End Function

Function Cut(pPath)
  Cut = FSO.GetFileName(pPath)
End Function
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Batya писал(а):Не обязательно выделять несколько папок. Работает и с одной папкой.
Было бы странно, если бы работало только с несколькими, но тем не менее в названиях должно быть это важное уточнение. Мне лично исходя из названия было непонятно.
Аватара пользователя
dude
Сообщения: 11
Зарегистрирован: Пт янв 21, 2011 06:02

Сообщение dude »

Batya писал(а):А я спрашиваю, что делать, если выделено несколько.
По логике вещей — создать для каждого из каталогов свой собственный список файлов.
Batya писал(а):Пока не совсем въехал, когда вставлять перед новой папкой пустые строки, а когда - нет.

Между первого уровня вложенности подкаталогами, между под-подкаталогами — без пустой строки.
Или вообще обойтись без этих строк. Ведь идея была в том, чтобы можно было как-то разобраться в каше из файлов и каталогов списка и создать хоть намек на структуру. Я лишь обрисовал один из возможных вариантов структуры списка.
Batya писал(а):Попробуй пока такой вариант:
К сожалению, у меня скрипт выдает ошибку и сразу вылетает.
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

dude писал(а):К сожалению, у меня скрипт выдает ошибку и сразу вылетает.
Т.е. окно с ошибкой даже пропадает?
Serge Yolkin
Сообщения: 664
Зарегистрирован: Сб июл 25, 2009 11:12

Сообщение Serge Yolkin »

А если батник?

Код: Выделить всё

for /r %%i in (*.exe) do Echo %~fi & Pause
?
Для вывода в файл - & Pause заменить на >> имя_файла.txt
Для нескольких папок - цикл с шифтом и проверка if defined
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

dude писал(а):К сожалению, у меня скрипт выдает ошибку и сразу вылетает.
Перед закрытием окна ошибки нажми Ctrl+C. В буфере окажется текстовое содержимое ошибки. Покажи здесь это текст.
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Batya
Так я тоже самое предложил бы, только сперва бы понять, что имелось в виду под "вылетает". Зрительно это в любом случае не определить.
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Flasher писал(а):Список кидать в противоположную панель.
Тогда уж м.б. и дополнять, а не заменять?

Код: Выделить всё

TOTALCMD#BAR#DATA
%comspec% /c for /f "delims=" %d in ('chcp 1251^>nul^&type
%WL') do %%comspec%% /c "chcp 1251&(dir/b/s/on/a-d "%%d"&echo:)>>"%Tlist.lst""
%commander_path%\totalcmd.exe,24
всё выделенное >> список с полными путями

1
-1
полные пути, win-1251

*в предыдущих кнопках исправления (№№1,2) и "списки из разных папок отделять пустыми строками" (№3)
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Tol!k писал(а):Тогда уж м.б. и дополнять, а не заменять?
Да, такое поведение устроит. Пустые строки можешь сделать между всеми подкаталогами, а не только папками, что в корне?
Jonmey
Сообщения: 59
Зарегистрирован: Пн сен 27, 2010 14:01

Сообщение Jonmey »

Batya
Ваш скрипт работает шикарно. И сортирует все правильно в логическом порядке. Всего пару секунд на 6000 файлов.
Спасибо большое.

А второй (по расширениям) тоже работает без проблем.
Ответить