Консультация № 173842
30.10.2009, 18:10
25.00 руб.
31.10.2009, 20:26
0 27 2
Здравствуйте уважаемые эксперты! Подскажите пожалуйста как решить проблему.
Имеется каталог (и подкаталоги) с картинками. Более 5000 штук. Имеется файл лист (*.txt) c более чем 3000 названиями файлов в этом каталоге. Надо скопировать по этому файл листу файлы в другой каталог.
Желательно (но не обязательно, можно валить все файлы в кучу) с сохранением структуры основного каталога.
ПРимер файл листа:
zmenenie_razmera_geografiyu.jpg
images2008/dvd-muz-it-danze-m.jpg
images2008/dvd-dark-sekt-m.jpg
images2/cd-ss-zabprikl_m.jpg
....
....
....
Все пути относительно основного каталога.
Заранее СПАСИБО!!!

Обсуждение

давно
Модератор
137394
1850
30.10.2009, 18:42
общий
Sergepon:
Был бы этот вопрос в рассылке
/ КОМПЬЮТЕРЫ И ПО / Программирование / Basic/VBA или
/ КОМПЬЮТЕРЫ И ПО / Программирование / Программирование нетривиальных задач
ответил бы с превеликим удовольствием, а на эту рассылку не подписывался
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
30.10.2009, 18:45
общий
Наверное, для этого нужно писать специальную утилиту на языке программирования: построковое считывание файла *.txt, а затем копирование файла со считанным именем в указанную папку. Мне кажется, это не очень сложно. К сожалению, у меня это не получится - я сейчас в цейтноте.
Неизвестный
30.10.2009, 18:46
общий
Megaloman:
А Вы можете записать ответ в мини-форум.
Неизвестный
30.10.2009, 18:47
общий
Модераторы:
Нельзя ли перенести этот вопрос в
/ КОМПЬЮТЕРЫ И ПО / Программирование / Basic/VBA или
/ КОМПЬЮТЕРЫ И ПО / Программирование / Программирование нетривиальных задач ?
давно
Модератор
137394
1850
30.10.2009, 21:44
общий
Администрация:
У меня готово решение задачи. Я подписан на рассылку Программирование нетривиальных задач. У меня не появилась кнопка ответа на вопрос. Готов выложить решение в мини-форуме (я отвечаю за слова, написанные мной в минифоруме вопроса выше), если это не противоречит политике и правилам портала.
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
30.10.2009, 23:00
общий
Megaloman:
В самом конце вопроса, перед фразой "Oтветов пока не поступило", есть ссылка "ответить", может ею можно воспользоваться..
давно
Модератор
137394
1850
30.10.2009, 23:05
общий
SerKuz:
В самом конце вопроса, перед фразой "Oтветов пока не поступило", есть ссылка "ответить", может ею можно воспользоваться..
- 332 раза я это проделывал, находил эту кнопку, а на 333 раз в упор не вижу
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
30.10.2009, 23:40
общий
Megaloman:
Раньше видели, а сейчас эту ссылку не найдете или что? =)
Кидайте мне экзешник - я выложу здесь
давно
Модератор
137394
1850
30.10.2009, 23:53
общий
Экзешника не существует - это текстовый файл с расширением .vbs
Он запускается как обычный исполнимый файл. Ничего в систему дополнительно ставить не надо.
В этом-то и прелесть js и vbs скриптов.
Будь это бесплатный вопрос - давно бы уже выложил. А так опасаюсь нанести финансовый ущерб порталу.
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
31.10.2009, 00:11
общий
Megaloman:
Я-ж пошутил =)
Кстати vbs как запускается, через wscript.exe? Если да, то у меня не запустится - я от греха переименовал его расширение
давно
Мастер-Эксперт
259041
7459
31.10.2009, 04:18
общий
Sergepon:
Моя программа Export.cmd несколько лет успешно синхронизирует файлы дом-работа, упаковывая на флэшку новые или свежие файлы, сравнивая списки типа Home\Foto.lst и Job\Foto.lst , содержащие строки Nature\Fauna\Kotik.jpg//2009.10.11 17:4
Алгоритм: если в локал-списке отражено наличие файла Kotik.jpg, а в даль-списке его нет, или его дата-время (правее разделителя // , округлено до десятков минут) старее, то Kotik.jpg упакуется на флэшку с подпутём.
Недостаток: прога-создатель CreLst.cmd авто-создаёт .lst-списки в DOS-кодировке, которая некорректно отображает кириллицу при попытке зачитать в WinБлокноте. У меня всё работает, потому что Cmd-обработчик списков читает списки тоже в DOS-кодировке.
Поэтому, если Вам не предложат программу на более современных языках, то я могу приспособить свои прог-строки для Вашей задачи.
Неизвестный
31.10.2009, 13:29
общий
Megaloman:

У меня не появилась кнопка ответа на вопрос.


У меня кнопка появилась. Могу тоже разместить.

Готов выложить решение в мини-форуме (я отвечаю за слова, написанные мной в минифоруме вопроса выше), если это не противоречит политике и правилам портала.


А каким правилам портала это противоречит?
давно
Модератор
137394
1850
31.10.2009, 17:07
общий
Гуревич Александр Львович:
Мне помнится, за неотвеченные платные вопросы денежки возвращаются вопрошающему. Ответ в минифоруме - не ответ, а реплика.
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
давно
Модератор
137394
1850
31.10.2009, 17:31
общий
SerKuz:
У вас есть еще один вариант - я этот скрипт отлаживал как макрос в Excel. Смею Вас уверить - работает. По идее, вообще это даже полезно - без хлопот можно в таблицу вывести протокол работы. Хотя, в принципе, скриптом можно вывести протокол в текстовый файл. Кстати, вот возможный вариант решения - макрос в Excel на VBA. Еще вариант - написать батник на основе команды For. Будет скучно - сделаю.
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
давно
Мастер-Эксперт
680
2811
31.10.2009, 17:46
общий
Т.к. решение в VBA уже готово, начнем с того, что перенесем вопрос в VBA.
А дальше посмотрим.
Неизвестный
31.10.2009, 18:12
общий
Megaloman:
Вы не ошиблись адресатом?) Мне не нужен скрипт, просто было интересно какой программой запускается vbs =)
давно
Мастер-Эксперт
680
2811
31.10.2009, 20:30
общий
это ответ
Здравствуйте, Sergepon.
По просьбе эксперта Megaloman размещаю его ответ на Ваш вопрос (два способа).

"Уважаемый Sergepon! Я решил Вашу задачу двумя способами.

1. С помощью vbs - скрипта. Готовый скрипт можно скачать здесь
Код:
' Скрипт из текстового файла считывает список файлов с путями относительно исходной указанной директории
' При реальном наличии указанных файлов копирует их в выходную директорию
' Структура директорий при копировании сохраняется.

FromDir = "D:\_Удали это" ' Откуда копируем
OutDir = "D:\_Удали это тоже" ' Куда копируем
ListFiles = "D:\_Удали это\Список файлов.txt" ' Текстовый файл с путями копируемых файлов относительно папки Откуда копируем

Set FSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
FSO.CreateFolder OutDir ' Создаём папку, куда копируем
On Error GoTo 0

If FSO.FolderExists(OutDir) Then ' Если папка существует
On Error Resume Next
Set FList = FSO.OpenTextFile(ListFiles, 1, False) ' открываем файл со списком

If Err.Number = 0 Then ' Если файл со списком успешно открыт
On Error GoTo 0
Mass = Split(Replace(Trim(Replace(FList.ReadAll, Chr(10), "")),"/",""), Chr(13)) ' Читаем список файлов в массив
FList.Close

First = LBound(Mass)
Nfiles = UBound(Mass)

j = 0
For i = First To Nfiles
InPath = FromDir + Mass(i)

If Len(Trim(Mass(i))) <> 0 Then
If FSO.FileExists(InPath) Then
mDir = Split(Mass(i), "")
nnn = UBound(mDir) - 1

If nnn >= 0 Then
MakeDir = OutDir

For n = 0 To nnn

If Len(Trim(mDir(n))) <> 0 Then
MakeDir = MakeDir + mDir(n) + ""

If Not FSO.FolderExists(MakeDir) Then ' Если папка не существует
On Error Resume Next
FSO.CreateFolder MakeDir ' Создаём папку, куда копируем конкретный файл
On Error GoTo 0
'''' MsgBox (MakeDir)
End If

End If

Next

End If

InPath = FromDir + Mass(i)
OutPath = OutDir + Mass(i)
OutFileName = FSO.GetFileName(OutPath)

If Len(Trim(OutFileName)) <> 0 Then
On Error Resume Next
Call FSO.CopyFile(InPath, OutPath, True) ' Создаём папку, куда копируем конкретный файл

If Err.Number <> 0 Then
Mess = MsgBox("При копировании" + InPath + vbCrLf + "в файл " + OutPath + vbCrLf + Err.Description, 0, "Ошибка при копировании файла")
Else
j = j + 1
End If
On Error GoTo 0

End If

Else
Mess = MsgBox("При копировании" + InPath + vbCrLf + "Исходный файл отсутствует", 0, "Ошибка при копировании файла")
End If

End If

Next

Mess = MsgBox("Скопировано " + CStr(j) + " файлов", 0, "Копирование файлов завершено")

Else ' Если файл со списком открыть не удалось
Mess = MsgBox(ListFiles + " " + Err.Description, 0, "Ошибка при открытии файла со списком")
End If
Else ' Если папку создать не удалось
Mess = MsgBox(OutDir + " Папку создать не удалось", 0, "Ошибка при создании выходной папки")
End If
В тексте скрипта необходимо подправить путь исходной директории, путь целевой директории (оба пути с \ на конце), а также путь к текстовому файлу со списком файлов.
Приведенный код скопируйте, например, в блокнот с сохраните в файл с расширением .vbs
Он запускается как обычный исполнимый файл. Ничего в систему дополнительно ставить не надо.

2. С помощью командного файла.
Код:
Echo Off
cls

Set Spis=D:\_Исходные файлы\Список файлов.txt
Set FromDir=D:\_Исходные файлы\
Set OutDir=D:\_Исходные файлы (дубль)\

FOR /F "usebackq delims==" %%i in ("%Spis%") do Call :CopyWithDir "%FromDir%%%i" "%OutDir%%%i"
GoTo End

:CopyWithDir

IF NOT EXIST %1 GoTo End

md "%~d2%~p2"
Copy %1 %2

:End

Приведенный код должен быть в файле с расширением .bat
Однако тут есть тонкость - если есть имена файлов или директорий с русскими символами, и имена файлов в текстовом файле и имена файлов и директорий в bat-файле должны быть в DOS-кодировке. Обычно для этих целей я использую редактор файл-менеджера FAR.
Вот ссылка на готовый файл.

Оба решения оттестированы и работают. Тестировалось в Windows XP."
Неизвестный
31.10.2009, 21:34
общий
Для интереса проверил работу bat-файла (способ N 2).
Работает замечательно!
Только в составе путей, указываемых в bat-файле, не должно быть букв кириллицы.
Решение Megalomanа - просто супер!
Неизвестный
31.10.2009, 21:45
общий
Megaloman:
Только никак не могу понять, как считывается строка в текстовом файле?
Как работает:
FOR /F "usebackq delims==" %%i in ("%Spis%") ?
Неизвестный
31.10.2009, 22:47
общий
Да, мне тоже понравилось решение с батником. Не думал, что батником можно такое провернуть, в несколько строчек
давно
Мастер-Эксперт
259041
7459
01.11.2009, 02:43
общий
Cmd-файл (устаревшее назв bat-файл) может зачитать и обработать также и кириллический текстовый документ, но текстовый файл надо подготовить: либо внести DOS-предыскажения (исказится читаемость под WinБлокнотом), либо из меню Файл \ СохранитьКак пересохранить в Юникоде (объём тект-файла удвоится).
давно
Модератор
137394
1850
01.11.2009, 12:02
общий
Гуревич Александр Львович:
Цитата: Гуревич Александр Львович
Только в составе путей, указываемых в bat-файле, не должно быть букв кириллицы.
Цитата: Megaloman
имена файлов в текстовом файле и имена файлов и директорий в bat-файле должны быть в DOS-кодировке
Если и батник, и текстовый файл со списком файлов написаны в 866 кодировке, то всё работает. Я сознательно в батнике использовал русские имена, чтобы быть в этом уверенным во время тестирования.
Формат For списан с For /?. usebackq скорее всего совершенно не нужен, я его вовремя не вычистил. Проверять лень, т к сижу уже за третьим компом и восстанавливать папки с тестовыми файлами уже надоело.
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
02.11.2009, 11:24
общий
это ответ
Здравствуйте, Sergepon.
Так как разделитель в списке файлов "/" предполагаю, что у вас *NIX
Вот как это можно сделать на bash (проверено на GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu))



Приложение:
cd "каталог, откуда копировать" ; outdir="каталог, куда надо копировать" ; while read a ; do mkdir -p "${outdir}/${a%/*}" ; cp "${a}" "${outdir}/${a}" ; done <"список файлов"
Неизвестный
02.11.2009, 11:29
общий
В моем ответе "список файлов" - это файл со списком, если не понятно, а не список сам по себе.
Задача кстати совершенно тривиальная и пользовательская
Программирование тут почти не нужно
давно
Модератор
137394
1850
02.11.2009, 13:29
общий
Гуревич Александр Львович:
Я был не прав: usebackq нужен, так как я пути помещаю в цикле в кавычки ("%List%") . А вот вариант моего решения в (практически) одну строку
Код:
rem Все пути без кавычек, пути исходной и целевой папки без \ на конце

Set In=D:\Исходная папка 1
Set Out=D:\Исходная папка 2
Set List=D:\Список файлов.txt

FOR /F "usebackq delims=" %%I IN ("%List%") DO If Exist "%In%\%%I" md "%Out%%%~pI" | Copy "%In%\%%I" "%Out%\%%I"
Об авторе:
Понеже не словес красных бог слушает, но дел наших хощет
Неизвестный
08.11.2009, 12:26
общий
Megaloman:
Огромное спасибо всем участникам данного мини-форума. К сожалению, ранее ответить не удалось по ряду причин. Все сработало по первому способу Уважаемого Эксперта Megalomana, за что ему отдельное спасибо и причитающееся вознаграждение посредством WM. Только надо разобраться как перечислить WM. Надеюсь, администрация в лице Уважаемой Татьяны Михайловны мне поможет. Но пока буду разбираться сам.
давно
Мастер-Эксперт
680
2811
08.11.2009, 17:46
общий
Sergepon:
Вы все правильно сделали, деньги пришли. Я их сейчас переведу Megaloman'у.
Форма ответа