Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Как из папки выбрать в переменную уникальные имена файлов

Ответить
Настройки темы
CMD/BAT - Как из папки выбрать в переменную уникальные имена файлов

Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


День добрый,
подскажите, запутался,

есть каталог, в нем файлы типа:
2010.07.21-xx_ab.zip
2010.06.14-xxx.zip
2010.08.21-xx_ab.zip
2010.09.14-xxx.zip
2010.07.11-xx_ab.zip
2010.06.04-xxx.zip
2010.08.26-xx_ab.zip
2010.02.14-xxx.zip

Мне нужна переменная в которой только уникальные имена, т.е. например x=xx_ab xxx

Затык в том, что у меня получается цикл в цикле:
1. бежать в каталоге по именам файлов
2. если в нашей переменной такое имя не встречалось, то set переменная=%переменная% %имя_текущего_файла%
в этом случае второй цикл не хочет просматривать переменную и тем более "на ходу" ее дополнять
Код: Выделить весь код
@echo off
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion
set idfile=
for /f "tokens=1* delims=-" %%i in ('dir *.zip /b') do (
for /f "delims= " %%x in (!idfile!) do (
if not %%x == %%j set idfile=!idfile! %%j
)
)
@echo idfile=%idfile%
хотя если собрать все имена файлов в каталоге в 1 переменную, то работает

Код: Выделить весь код
@echo off
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion
set idfile=
for /f "tokens=1* delims=-" %%i in ('dir *.zip /b') do (
set idfile=!idfile! %%j
)
echo idfile=%idfile%
но мне нужны в переменной только уникальные имена! иначе дальнейшую обработку не могу организовать...

Отправлено: 21:48, 22-07-2010

 

Старожил


Сообщения: 426
Благодарности: 108

Профиль | Отправить PM | Цитировать


Уточните проблему более подробными примерами - ничего не понятно.

-------
Как сказало Дерево Дровосеку: "я - пень".


Отправлено: 19:02, 23-07-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


Уточняю:
каждый день на сервере появляются файлы бэкапа в виде zip-архивов.
Эти файлы ВСЕ в имени сначала имеют дату создания, затем уникальное имя - то с чего сделан бэкап.
Этого "то с чего сделан бэкап" у меня около 12 штук.
Вопрос: в каталоге может быть несколько тысяч файлов, но мне нужно знать именно их уникальные имена, то есть с чего это бэкапы.

Пример:
2010.07.21-xx_ab.zip, где
2010.07.21 - дата
xx_ab - уникальное имя

Более того, я уже даже решил проблему, но по извращенному:
Код: Выделить весь код
for /f "tokens=1* delims=-" %%i in ('dir *.zip /b') do (echo. > %%j.id)
Эта строка пробегает по именам всех zip в каталоге и отбрасывая первую часть с датой, создает пустой файлик с расширением *.id.
В конечном итоге по этим файликам я точно знаю какие именно бэкапы в каталоге и могу уже использовать их имена для задания маски для дальнейшей обработки.
(мне нужно каждого типа бэкапов хранить всего 5 последних штук, т.е. с сервера-1 5 последних, сервера-2 5 последних и т.д)

Хочу услышать критику и возможно решение через find.
Может кто-то покажет красивее?

Не 1й раз пишу на этом форуме, и хочу предупредить, я хочу решение ИМЕННО в виде bat, на худой конец vbs.
Не предлагайте варианты стороннего ПО, все должно работать "из коробки".

P.S. Почему не обрабатывается переменная цикла в цикле??
Не помню таких ограничений.
т.е. например for %%i do (for %%x do ...) - как обойти ограничение что %х игнорируется??

Не понимаю я
SetLocal EnableExtensions
SetLocal EnableDelayedExpansion
или вернее для передачи переменной в цикл надо ее брать в !переменная!
а как взять в "!" переменную %%i?

Понимаю вопрос задал криво, но вот как есть

Отправлено: 21:21, 23-07-2010 | #3

QRS QRS вне форума

Ветеран


Сообщения: 630
Благодарности: 111

Профиль | Отправить PM | Цитировать


могу предложить первым циклом забросить имена в файл:

Код: Выделить весь код
for /f "tokens=1* delims=-" %%i in ('dir *.zip /b') do (
echo %%J >> 1.tmp
)
далее сортируем и идем перебором:

Код: Выделить весь код
for /f "delims= " %%x in ('sort 1.tmp') do (
if '!last1!'  NEQ '%%x' set idfile=!idfile! %%x
set last1=%%x
)
echo !idfile!
у себя проверил - работает.
ps: лучше взять временное имя файла и в конце удалить его.
Это сообщение посчитали полезным следующие участники:

Отправлено: 21:42, 23-07-2010 | #4


Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1273
Благодарности: 1030

Профиль | Отправить PM | Цитировать


Цитата Banzaika:
мне нужно каждого типа бэкапов хранить всего 5 последних штук, т.е. с сервера-1 5 последних, сервера-2 5 последних и т.д »
Значит все остальное удаляем:
Код: Выделить весь код
@Echo Off
SetLocal EnableDelayedExpansion
Set Source=C:\Source
Set NumSavedFiles=5

Set Count=1
Echo.>_UniqueNames.log
For /F "Tokens=1* Delims=-" %%A In ('Dir /B "%Source%\*.zip"') Do (
	Find "%%B" _UniqueNames.log 1>nul 2>&1||Echo %%B>>_UniqueNames.log&&Call :Func "!Count!"
)
Del /F /Q _UniqueNames.log 1>nul 2>&1
EndLocal
GoTo :EOF

:Func
	For /F "Skip=%~1 Tokens=*" %%C In ('Type _UniqueNames.log') Do (
		For /F "Skip=%NumSavedFiles% Tokens=*" %%D In ('Dir /B /O-D /TC "%Source%\*%%C"') Do Del /F /Q "%Source%\%%D" 1>nul 2>&1
	)
	Set /A Count+=1
Это сообщение посчитали полезным следующие участники:

Отправлено: 13:59, 24-07-2010 | #5


Новый участник


Сообщения: 14
Благодарности: 0

Профиль | Отправить PM | Цитировать


QRS
В цикле сортировки, если верить подсказке на команду if то операторы сравнения (neq - не равно) допустимо использывать при "расширенной обработке команд"... Точно ли не нужен ключ "/i"???
И не совсем понял сколько раз нужно делать цикл? Ведь будут исключены лишь явно повторяющиеся значения последовательности, например 1123112 превратится в 12312. Мне то на выхлопе нужно получить просто 123...
Может я что-то не правильно понял про команду sort? (фокус с созданием файлов в том что при выполнении цикла они др др заменяют, но в итоге остаются лишь "уникальные")

El Sanchez
Круто, только можно прокомментировать строки? Если честно не все понимаю... хотя и вижу сценарии не 1й раз...

Последний раз редактировалось Banzaika, 24-07-2010 в 16:02.


Отправлено: 15:44, 24-07-2010 | #6


Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1273
Благодарности: 1030

Профиль | Отправить PM | Цитировать


Banzaika,

Цитата El Sanchez:
Echo.>_UniqueNames.log »
Пишем пустую строку в файл _UniqueNames.log, где будет список уникальных имен.

Цитата El Sanchez:
For /F "Tokens=1* Delims=-" %%A In ('Dir /B "%Source%\*.zip"') Do (
Find "%%B" _UniqueNames.log 1>nul 2>&1||Echo %%B>>_UniqueNames.log&&Call :Func "!Count!"
) »
Основной цикл. Из вывода команды Dir берем из каждой строки все, что после дефиса, т.е. уникальное имя (переменная %B). Ищем имя в файле _UniqueNames.log (Find "%%B" _UniqueNames.log 1>nul 2>&1) и, если в файле его еще нет (||), то записываем его (Echo %%B>>_UniqueNames.log). Если запись произведена (&&), то вызываем процедуру Func с передаваемым в нее параметром Count - количество строк для пропуска.

Сама процедура:
Цитата El Sanchez:
:Func
For /F "Skip=%~1 Tokens=*" %%C In ('Type _UniqueNames.log') Do (
For /F "Skip=%NumSavedFiles% Tokens=*" %%D In ('Dir /B /O-D /TC "%Source%\*%%C"') Do Del /F /Q "%Source%\%%D" 1>nul 2>&1
)
Set /A Count+=1 »
, где For /F "Skip=%~1 Tokens=*" %%C In ('Type _UniqueNames.log') - печатаем наш лог-файл и пропускаем количество строк, заданное в ключевом слове Skip. %~1 - это
наше количество строк Count, переданное из основного цикла. Skip не может начинаться с нуля, по-этому в самом начале и записана пустая строка в _UniqueNames.log.
В попадет последняя строка, содержащая уникальное имя.

For /F "Skip=%NumSavedFiles% Tokens=*" %%D In ('Dir /B /O-D /TC "%Source%\*%%C"') Do Del /F /Q "%Source%\%%D" 1>nul 2>&1 - сортируем все файлы, содержащие в себе уникальное имя %C,
начиная с самого нового (/O-D /TC), пропускаем нужные 5 файлов (%NumSavedFiles%), а все остальное удаляем.

Set /A Count+=1 - увеличиваем количество строк, т.к. при следующем найденном уникальном имени нужно будет пропускать в _UniqueNames.log на строку больше.

Отправлено: 19:45, 24-07-2010 | #7


Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1273
Благодарности: 1030

Профиль | Отправить PM | Цитировать


Banzaika,
Вариант №2, попроще и покороче, но время выполнения дольше:
Код: Выделить весь код
@Echo Off
Set Source=C:\Source
Set NumSavedFiles=5

For /F "Tokens=1* Delims=-" %%A In ('Dir /B "%Source%\*.zip"') Do (
	For /F "Skip=%NumSavedFiles% Tokens=*" %%C In ('Dir /B /O-D /TC "%Source%\*%%B"') Do Del /F /Q "%Source%\%%C"
)

Отправлено: 11:38, 25-07-2010 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - Как из папки выбрать в переменную уникальные имена файлов

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Записать имя папки в которой лежит батник в переменную а потом эту же папку переим. bobr95 Скриптовые языки администрирования Windows 8 10-04-2012 18:42
Имена файлов при двухпроходном кодировании. HiDux Видео и аудио: обработка и кодирование 12 28-08-2009 00:09
CMD/BAT - [решено] Как имена файлов расположенных в одной папке записать в текстовый файл? Nun-Nun Скриптовые языки администрирования Windows 6 12-05-2009 21:44
Интерфейс - Имена файлов в папке Windows\Media Билл Гейтс Microsoft Windows 2000/XP 3 09-11-2008 13:10
после доса имена файлов: МУЗЫ~1 (Музыка) Denis Shutka Microsoft Windows 2000/XP 6 16-02-2005 23:49




 
Переход