Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Как дописать случайные числа к началам имён файлов в каталоге (http://forum.oszone.net/showthread.php?t=287115)

mwz 28-08-2014 00:03 2395092

Как дописать случайные числа к началам имён файлов в каталоге
 
Знаю что задача простенькая -- но давно не занимался такого класса задачками...

Приписать случайные (достаточно трёх-пяти разрядов) числа и разделитель к началу имён всех файлов каталога (подкаталоги не интересуют), т.е. вместо, например,

...
ofigennaya_pesnya.mp3
prosto_obaldenno.mp3
...

получить типа:
...
32761_prosto_obaldenno.mp3
...
56845_ofigennaya_pesnya.mp3
...

(желательно с одинаковым числом цифр, т.е., например, не 53, а 00053 при пятиразрядных, или 053 при трёхразрядных).
Названия, приведённые для примера, подсмотрены на одном из чужих компов. :)

Iska 28-08-2014 01:20 2395116

Как-то так:
Код:

@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

Целевая папка указывается аргументом пакетного файла. Также можно просто перетащить папку на пакетный файл.

Vadikan 28-08-2014 01:32 2395125

mwz, а в чем тайный смысл случайных префиксов? Ведь тогда еще и придется проверять, не оказались ли случайные неслучайными :) Инкрементные проще, короче и надежнее.

Код:

$global:i=12345
dir c:\test\ -Filter *.mp3 | Rename-Item -NewName { "$i-$($_.Name)"; $global:i++ }


mwz 28-08-2014 01:38 2395127

Iska, отлично, спасибо!
Маленькая погрешность: не переименовались файлы, имена которых содержат восклицательный знак.

Vadikan, собственно, конкретную задачу можно понять из примеров: [достаточно] случайным образом пересортировать порядок следования файлов с неслучайными именами. :)

Vadikan 28-08-2014 02:03 2395130

Цитата:

Цитата mwz
собственно, конкретную задачу можно понять из примеров »

Собственно, для этого надо быть Друзём, который еще и знает о функции "Воспроизводить в случайном порядке".

Без проверки на уникальность:
Код:

dir c:\test\ -Filter *.mp3 | Rename-Item -NewName { "$(Get-Random -min 10000 -max 99999)-$($_.Name)";  }

Iska 28-08-2014 02:57 2395140

Цитата:

Цитата mwz
Маленькая погрешность: не переименовались файлы, имена которых содержат восклицательный знак. »

Это особенность работы пакетных файлов с включённым режимом отложенного раскрытия переменных окружения (впрочем, аналогичные неприятные «особенности» наличествуют у всех языков, поддерживающих подобные «препроцессорные макросы»).

Приведённый ранее код можно заменить, например, таким, используя двойное раскрытие переменных окружения по «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

Цитата:

Цитата mwz
Vadikan, собственно, конкретную задачу можно понять из примеров: [достаточно] случайным образом пересортировать порядок следования файлов с неслучайными именами. »

Заранее это понять сложно. Тем паче, что глобальная задача опять-таки неясна: зачем надо менять порядок следования файлов?

Если для воспроизведения — так ведь практически все известные мне плееры имеют функцию «перемешивания» файлов в списке. Можно даже просто составить список .m3u из исходных файлов в произвольном порядке и «скормить» его плееру.

mwz 28-08-2014 11:19 2395252

Vadikan, попробовал cmd-файл (Windows-7); увы:
"Rename-Item" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
(глубже пока не полез).

Цитата:

Цитата Iska
Тем паче, что глобальная задача опять-таки неясна »

Извиняюсь, уже спал на ходу когда увидел и скрипт, и вопрос -- почему и ответил туманно и вкратце.

Да, задача чисто утилитарная: перемешивание музыкальных файлов, которые затем кидаются на флэшку формата FAT32 (плеер в автомобиле воспроизводит их в натуральном порядке, т.е. в порядке следования их в таблице FAT) и могут быть затем переименованы назад (почему и желательно было одинаковое число цифр: для автоматизации) с сохранением случайности порядка в таблице FAT.

.m3u -- у плеера с ними какие-то проблемы (похоже что в случае, если файл, стоящий на очереди, удалён с флэшки: после этого идёт сообщение типа "Неверный формат" и флэшку приходится перезаливать, поскольку перестаёт играть её вообще). Опять же список надо всё равно сортировать, что и отметил Vadikan.

Случайный порядок воспроизведение -- да, есть; но у алгоритма конкретного плеера оказались "свои музыкальные предпочтения": даже при количестве файлов порядка тысячи (5 знаков в исходном вопросе я взял с запасом, зная что на сложность решения это не должно повлиять) некоторые композиции он может прокрутить по пять раз в час, а некоторые -- раз в пару месяцев.

Промежуточный выход был найден: предварительная сортировка по размеру и скидывание в этом порядке (файлы, подготовленные к записи на флэшку, лежат жёсткими ссылками в отдельном каталоге и потихоньку пополняются, файлы же, удалённые с флэшки, переносятся отсюда в другую папку чтобы не зацепить их снова; установленная утилита LinkShellExtention зрительно проявляет жёсткие ссылки в основном каталоге и сразу видно, что файл или уже лежит в папке с подготовленными, или что заведомо не должен там лежать). Но некоторые длинные одинаковые композиции в разных вариациях оказались достаточно близки друг к другу.

А тут как раз надо перезалить флэшку -- и я рискнул задать вопрос, зная что каких-то трудностей он не должен вызвать (правда, думал что будет использован цикл for и переменная %random% -- то направление, которое я собирался попробовать, не сообразив что можно использовать dir с передачей результата на дальнейшую обработку, как в последнем скрипте у Vadikan; извинения за уточнение с восклицательными знаками: понятно что в данном случае это некритично, и пяток-десяток файлов можно и вручную потасовать).

Vadikan 28-08-2014 12:58 2395302

mwz, это PowerShell, другую консоль надо открыть или так. Спасибо за развернутое описание задачи :)

Iska 28-08-2014 15:28 2395355

mwz, спасибо, теперь ясно. Разве что — я бы не переименовывал оригинальные файлы, а копировал результирующие файлы под новым именем в отдельный каталог.

mwz 28-08-2014 23:14 2395549

Цитата:

Цитата Iska
я бы не переименовывал оригинальные файлы, а копировал результирующие файлы под новым именем в отдельный каталог »

Тут свои тараканы соображения. Иначе запутаюсь совсем. :)
А так и места не занимают (хардлинки ж, а их и переименовать без влияния на двойников в основном каталоге можно как угодно, и если изменять, типа добавления или правки тэгов в основном каталоге (и наоборот: в каталоге подготовленном для заливки) -- сразу и в хардлинках это будет отражено; при условии, разумеется, что не происходит удаления исходного файла с записью откорректированного на его место -- но в этом случае сразу пропадает метка жёсткой связи), и видно что где.

Цитата:

Цитата Vadikan
это 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


Vadikan 28-08-2014 23:30 2395554

mwz, а трюки те же - скопировал код, открыл консоль, нажал ПКМ. И настраивать ничего не надо.

Iska 28-08-2014 23:52 2395561

Цитата:

Цитата mwz
А так и места не занимают (хардлинки ж, »

Тю, дурень… я как-то не соотнёс, что ранее упомянутые жёсткие ссылки — это и есть наши файлы. Я имел в виду — можно ведь копировать переименованные файлы сразу на флэшку, так?

Цитата:

Цитата mwz
И даже не знаю, имеет ли смысл "учить старую собаку новым трюкам" в этой области: особых задач не предвидится... »

Имеет. Я вон тоже «неспешно учусь» ему, э… лет шесть уже, пожалуй ;).

mwz 29-08-2014 01:17 2395576

Цитата:

Цитата Vadikan
а трюки те же »

А, я имел в виду скрипты сценарии.
А этот трюк я уже проделал, и даже отчёт приложил к предыдущему сообщению. :)

Цитата:

Цитата Iska
можно ведь копировать переименованные файлы сразу на флэшку, так? »

Добавляю случайный префикс к хардлинкам, копирую их на флэшку в алфавитном (== теперь уже случайном) порядке, и группами убираю префиксы на флэшке и у хардлинков, восстанавливая статус кво. Всегда можно сравнить содержимое флэшки и исходника и, если новые файлы добавлять не в исходный каталог, а в его временный подкаталог (и перемещать на место только перед перезаливкой), то можно сравнением увидеть, что удалено с флэшки -- и перекинуть те хардлинки, соответствий которым нет на флэшке, в папку отработанных.

Ну а оставшиеся + новые при следующей заливке будут пересортированы уже в другом порядке (что бывает психологически заметно, правда, при относительно малом количестве записей, когда уже знаешь, за какой песней пойдёт какая: такой пересортировкой вносится элемент неожиданности :) ).

Vadikan 29-08-2014 13:58 2395764

Цитата:

Цитата mwz
А этот трюк я уже проделал, и даже отчёт приложил к предыдущему сообщению. »

Судя по времени последнего редактирования сообщения 10, это было сделано уже после моего ответа 11.

Цитата:

Цитата mwz
Результат тоже хороший -- и тоже споткнулось на некоторых символах (на квадратной скобке, насколько понимаю); »

Я не смог воспроизвести ошибку из сообщения 10. Она, кстати, указывает на отсутствующие файлы.
Код в сообщении 5 корректно переименовал файлы
Dope Smugglaz - The World [pmt rmx].mp3
Caetano Veloso - Cafe Copacabana [C&B] - Garota de Ipanema.mp3

Цитата:

Цитата mwz
разделителем же стал не знак подчёркивания, а дефис, хотя в команде вижу именно знак подчёркивания »

Там именно дефис. Подчеркивание не будет работать в этой конструкции, но для глобальной задачи это никакого значения не имеет.

mwz 29-08-2014 18:40 2395898

Цитата:

Цитата Vadikan
это было сделано уже после моего ответа 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

Две круглых -- без проблем.
Первая круглая, вторая квадратная -- без проблем.
Снова две квадратных -- снова ошибка как в первом моём отчёте.


Опять же -- информация чисто для сведения, мою задачу вы мне уже решили с достаточной степенью точности. :)


Время: 11:29.

Время: 11:29.
© OSzone.net 2001-