Показать полную графическую версию : [решено] Как дописать случайные числа к началам имён файлов в каталоге
Знаю что задача простенькая -- но давно не занимался такого класса задачками...
Приписать случайные (достаточно трёх-пяти разрядов) числа и разделитель к началу имён всех файлов каталога (подкаталоги не интересуют), т.е. вместо, например,
...
ofigennaya_pesnya.mp3
prosto_obaldenno.mp3
...
получить типа:
...
32761_prosto_obaldenno.mp3
...
56845_ofigennaya_pesnya.mp3
...
(желательно с одинаковым числом цифр, т.е., например, не 53, а 00053 при пятиразрядных, или 053 при трёхразрядных).
Названия, приведённые для примера, подсмотрены на одном из чужих компов. :)
Как-то так:
@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFolder=%~1
set sTemplate=00000
if defined sSourceFolder (
if exist "%sSourceFolder%\." (
for /f "usebackq delims=" %%i in (
`dir /b /a:-d "%sSourceFolder%\*.*" 2^>nul`
) do (
set sPredicate=%sTemplate%!random!
ren "%sSourceFolder%\%%~i" "!sPredicate:~-5!_%%~i"
)
) else (
echo Can't find source folder [%sSourceFolder%].
exit /b 2
)
) else (
echo Usage: %~nx0 ^<Source folder^>
exit /b 1
)
endlocal
exit /b 0
Целевая папка указывается аргументом пакетного файла. Также можно просто перетащить папку на пакетный файл.
mwz, а в чем тайный смысл случайных префиксов? Ведь тогда еще и придется проверять, не оказались ли случайные неслучайными :) Инкрементные проще, короче и надежнее.
$global:i=12345
dir c:\test\ -Filter *.mp3 | Rename-Item -NewName { "$i-$($_.Name)"; $global:i++ }
Iska, отлично, спасибо!
Маленькая погрешность: не переименовались файлы, имена которых содержат восклицательный знак.
Vadikan, собственно, конкретную задачу можно понять из примеров: [достаточно] случайным образом пересортировать порядок следования файлов с неслучайными именами. :)
собственно, конкретную задачу можно понять из примеров »
Собственно, для этого надо быть Друзём, который еще и знает о функции "Воспроизводить в случайном порядке".
Без проверки на уникальность:
dir c:\test\ -Filter *.mp3 | Rename-Item -NewName { "$(Get-Random -min 10000 -max 99999)-$($_.Name)"; }
Маленькая погрешность: не переименовались файлы, имена которых содержат восклицательный знак. »
Это особенность работы пакетных файлов с включённым режимом отложенного раскрытия переменных окружения (впрочем, аналогичные неприятные «особенности» наличествуют у всех языков, поддерживающих подобные «препроцессорные макросы»).
Приведённый ранее код можно заменить, например, таким, используя двойное раскрытие переменных окружения по «call»:
@echo off
setlocal enableextensions disabledelayedexpansion
set sSourceFolder=%~1
set sTemplate=00000
if defined sSourceFolder (
if exist "%sSourceFolder%\." (
for /f "usebackq delims=" %%i in (
`dir /b /a:-d "%sSourceFolder%\*.*" 2^>nul`
) do (
call set sPredicate=%sTemplate%%%random%%
call ren "%sSourceFolder%\%%~i" "%%sPredicate:~-5%%_%%~i"
)
) else (
echo Can't find source folder [%sSourceFolder%].
exit /b 2
)
) else (
echo Usage: %~nx0 ^<Source folder^>
exit /b 1
)
endlocal
exit /b 0
Vadikan, собственно, конкретную задачу можно понять из примеров: [достаточно] случайным образом пересортировать порядок следования файлов с неслучайными именами. »
Заранее это понять сложно. Тем паче, что глобальная задача опять-таки неясна: зачем надо менять порядок следования файлов?
Если для воспроизведения — так ведь практически все известные мне плееры имеют функцию «перемешивания» файлов в списке. Можно даже просто составить список .m3u из исходных файлов в произвольном порядке и «скормить» его плееру.
Vadikan, попробовал cmd-файл (Windows-7); увы:
"Rename-Item" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
(глубже пока не полез).
Тем паче, что глобальная задача опять-таки неясна »
Извиняюсь, уже спал на ходу когда увидел и скрипт, и вопрос -- почему и ответил туманно и вкратце.
Да, задача чисто утилитарная: перемешивание музыкальных файлов, которые затем кидаются на флэшку формата FAT32 (плеер в автомобиле воспроизводит их в натуральном порядке, т.е. в порядке следования их в таблице FAT) и могут быть затем переименованы назад (почему и желательно было одинаковое число цифр: для автоматизации) с сохранением случайности порядка в таблице FAT.
.m3u -- у плеера с ними какие-то проблемы (похоже что в случае, если файл, стоящий на очереди, удалён с флэшки: после этого идёт сообщение типа "Неверный формат" и флэшку приходится перезаливать, поскольку перестаёт играть её вообще). Опять же список надо всё равно сортировать, что и отметил Vadikan.
Случайный порядок воспроизведение -- да, есть; но у алгоритма конкретного плеера оказались "свои музыкальные предпочтения": даже при количестве файлов порядка тысячи (5 знаков в исходном вопросе я взял с запасом, зная что на сложность решения это не должно повлиять) некоторые композиции он может прокрутить по пять раз в час, а некоторые -- раз в пару месяцев.
Промежуточный выход был найден: предварительная сортировка по размеру и скидывание в этом порядке (файлы, подготовленные к записи на флэшку, лежат жёсткими ссылками в отдельном каталоге и потихоньку пополняются, файлы же, удалённые с флэшки, переносятся отсюда в другую папку чтобы не зацепить их снова; установленная утилита LinkShellExtention зрительно проявляет жёсткие ссылки в основном каталоге и сразу видно, что файл или уже лежит в папке с подготовленными, или что заведомо не должен там лежать). Но некоторые длинные одинаковые композиции в разных вариациях оказались достаточно близки друг к другу.
А тут как раз надо перезалить флэшку -- и я рискнул задать вопрос, зная что каких-то трудностей он не должен вызвать (правда, думал что будет использован цикл for и переменная %random% -- то направление, которое я собирался попробовать, не сообразив что можно использовать dir с передачей результата на дальнейшую обработку, как в последнем скрипте у Vadikan; извинения за уточнение с восклицательными знаками: понятно что в данном случае это некритично, и пяток-десяток файлов можно и вручную потасовать).
mwz, это PowerShell, другую консоль надо открыть или так (http://www.outsidethebox.ms/15841/#sel=91:1,91:5). Спасибо за развернутое описание задачи :)
mwz, спасибо, теперь ясно. Разве что — я бы не переименовывал оригинальные файлы, а копировал результирующие файлы под новым именем в отдельный каталог.
я бы не переименовывал оригинальные файлы, а копировал результирующие файлы под новым именем в отдельный каталог »
Тут свои тараканы соображения. Иначе запутаюсь совсем. :)
А так и места не занимают (хардлинки ж, а их и переименовать без влияния на двойников в основном каталоге можно как угодно, и если изменять, типа добавления или правки тэгов в основном каталоге (и наоборот: в каталоге подготовленном для заливки) -- сразу и в хардлинках это будет отражено; при условии, разумеется, что не происходит удаления исходного файла с записью откорректированного на его место -- но в этом случае сразу пропадает метка жёсткой связи), и видно что где.
это PowerShell »
Я уже так и прикинул. Но я тоже, мягко говоря, "слабо владею PowerShell", и он у меня даже не настроен. И даже не знаю, имеет ли смысл "учить старую собаку новым трюкам" в этой области: особых задач не предвидится...
PS
Vadikan,
Да, скрипт PowerShell я выполнил, запустив его окно и вставив команду (с учётом имени каталога). :)
Результат тоже хороший -- и тоже споткнулось на некоторых символах (на квадратной скобке, насколько понимаю); разделителем же стал не знак подчёркивания, а дефис, хотя в команде вижу именно знак подчёркивания. Ошибки обработки -- такие:
PS C:\temp> dir c:\temp -Filter *.mp3 | Rename-Item -NewName { "$(Get-Random -mi
n 10000 -max 99999)-$($_.Name)"; }
Rename-Item : Не удается выполнить переименование, так как элемент в "Microsoft
.PowerShell.Core\FileSystem::C:\temp\Caetano Veloso - Cafe Copacabana [C&B] - G
arota de Ipanema.mp3" не существует.
строка:1 знак:40
+ dir c:\temp -Filter *.mp3 | Rename-Item <<<< -NewName { "$(Get-Random -min 1
0000 -max 99999)-$($_.Name)"; }
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.R
enameItemCommand
Rename-Item : Не удается выполнить переименование, так как элемент в "Microsoft
.PowerShell.Core\FileSystem::C:\temp\Dope Smugglaz - The World [pmt rmx].mp3" н
е существует.
строка:1 знак:40
+ dir c:\temp -Filter *.mp3 | Rename-Item <<<< -NewName { "$(Get-Random -min 1
0000 -max 99999)-$($_.Name)"; }
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.R
enameItemCommand
Rename-Item : Не удается выполнить переименование, так как элемент в "Microsoft
.PowerShell.Core\FileSystem::C:\temp\Lil Jon & The Eastside Boyz - Crunk Juice
[06] Da Blow Ft. G.mp3" не существует.
строка:1 знак:40
+ dir c:\temp -Filter *.mp3 | Rename-Item <<<< -NewName { "$(Get-Random -min 1
0000 -max 99999)-$($_.Name)"; }
+ CategoryInfo : InvalidOperation: (:) [Rename-Item], PSInvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.R
enameItemCommand
mwz, а трюки те же - скопировал код, открыл консоль, нажал ПКМ. И настраивать ничего не надо.
А так и места не занимают (хардлинки ж, »
Тю, дурень… я как-то не соотнёс, что ранее упомянутые жёсткие ссылки — это и есть наши файлы. Я имел в виду — можно ведь копировать переименованные файлы сразу на флэшку, так?
И даже не знаю, имеет ли смысл "учить старую собаку новым трюкам" в этой области: особых задач не предвидится... »
Имеет. Я вон тоже «неспешно учусь» ему, э… лет шесть уже, пожалуй ;).
а трюки те же »
А, я имел в виду скрипты сценарии.
А этот трюк я уже проделал, и даже отчёт приложил к предыдущему сообщению. :)
можно ведь копировать переименованные файлы сразу на флэшку, так? »
Добавляю случайный префикс к хардлинкам, копирую их на флэшку в алфавитном (== теперь уже случайном) порядке, и группами убираю префиксы на флэшке и у хардлинков, восстанавливая статус кво. Всегда можно сравнить содержимое флэшки и исходника и, если новые файлы добавлять не в исходный каталог, а в его временный подкаталог (и перемещать на место только перед перезаливкой), то можно сравнением увидеть, что удалено с флэшки -- и перекинуть те хардлинки, соответствий которым нет на флэшке, в папку отработанных.
Ну а оставшиеся + новые при следующей заливке будут пересортированы уже в другом порядке (что бывает психологически заметно, правда, при относительно малом количестве записей, когда уже знаешь, за какой песней пойдёт какая: такой пересортировкой вносится элемент неожиданности :) ).
А этот трюк я уже проделал, и даже отчёт приложил к предыдущему сообщению. »
Судя по времени последнего редактирования сообщения 10, это было сделано уже после моего ответа 11.
Результат тоже хороший -- и тоже споткнулось на некоторых символах (на квадратной скобке, насколько понимаю); »
Я не смог воспроизвести ошибку из сообщения 10. Она, кстати, указывает на отсутствующие файлы.
Код в сообщении 5 (http://forum.oszone.net/post-2395130-5.html) корректно переименовал файлы
Dope Smugglaz - The World [pmt rmx].mp3
Caetano Veloso - Cafe Copacabana [C&B] - Garota de Ipanema.mp3
разделителем же стал не знак подчёркивания, а дефис, хотя в команде вижу именно знак подчёркивания »
Там именно дефис. Подчеркивание не будет работать в этой конструкции, но для глобальной задачи это никакого значения не имеет.
это было сделано уже после моего ответа 11 »
Когда писал PS -- #11 не видел ещё (не обновил окно). :)
С дефисом -- действительно непринципиально; и означает, что я не разобрался в конструкции -$($_.Name). :(
Она, кстати, указывает на отсутствующие файлы »
В папке уже лежали тестовые файлы. Скрипт всё читал сам. Сейчас перепроверил на том же наборе. Не переименовались с теми же ошибками:"Caetano Veloso - Cafe Copacabana [C&B] - Garota de Ipanema.mp3"
"Dope Smugglaz - The World [pmt rmx].mp3"
"Lil Jon & The Eastside Boyz - Crunk Juice [06] Da Blow Ft. G.mp3"
Буду разбираться, почему: самому интересно (как-то раз уже сталкивался в WinXP с невозможностью переименования файла через TotalCmd -- и оказалось, что имя содержит невидимые символы, которые в Проводнике хотя бы проявились как, если не ошибаюсь, знак подчёркивания -- но им не были.
Однако полученные утилитарные результаты как с CMD, так и с PowerShell меня вполне устраивают -- так что это чисто для сведения.
PS
Ну вот, заставили пойти на площадку для выгула и для начала пробежаться по лужайке... тьфу.. по "Курсу выживания при создании сценариев" для PS. :)
Теперь понял, почему я решил что должен вводиться знак подчёркивания, а вводится дефис -- а из беглого чтения смог вынести предположение, что как раз в этой конструкции знак подчёркивания вместо дефиса должен отработать. И действительно сработало.
Заодно поменял слово "скрипты" в реплике выше на "сценарии".
Спасибо. :)
PPS
Vadikan,
...Cafe Copacabana [C&B] - ...
При замене второй квадратной скобки на круглую получаю более интересное сообщение:
PS C:\temp> dir c:\temp\ -Filter *.mp3 | Rename-Item -NewName { "$(Get-Random -m
in 10000 -max 99999)_$($_.Name)"; }
Rename-Item : Указанное сочетание подстановочных знаков недопустимо: Caetano Ve
loso - Cafe Copacabana [C&B) - Garota de Ipanema.mp3
строка:1 знак:41
Две круглых -- без проблем.
Первая круглая, вторая квадратная -- без проблем.
Снова две квадратных -- снова ошибка как в первом моём отчёте.
Опять же -- информация чисто для сведения, мою задачу вы мне уже решили с достаточной степенью точности. :)
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.