Пакетный файл Windows - Выберите (до) четырех случайных файлов в папке

Как следует из названия, я пытаюсь выбрать до четырех случайных файлов (обоев) из папки для дальнейшей обработки. Папка не содержит вложенных папок, только *.jpg, *.bmp и *.png (может содержать файл Thumbs.db, но я об этом уже позаботился).

Я прочитал все файлы с for цикл делает что-то похожее на массив, то я хотел бы запустить другой for Цикл для создания случайных чисел, которые будут действовать как индексы для выбора файлов.

setlocal enabledelayedexpansion
set "wps=1 2 3 4"
set /a ind = 0

for /f "tokens=* delims=" %%g in ('dir C:\Wallpapers /a:-h-s /b /s') do (
    set /a ind += 1
    set "!ind!=%%g"
)

for %%g in (%wps%) do (
    set /a "num = (((!random! & 1) * 1073741824) + (!random! * 32768) + !random!) %% %ind% + 1"
    echo Wallpaper %%g is #!num! - Title: "!!num!!"
)


Конечно, строка, которая отражает только вывод Wallpaper 1 is #118 - Title: "118" вместо Wallpaper 1 is #118 - Title: "C:\Wallpapers\Miami Skyline.jpg",

Поэтому мой конкретный вопрос: как я могу дважды развернуть переменную внутри for цикл?

[Примечание #1: строка, которая создает случайное число, должна быть настолько длинной, потому что она дает хорошее случайное распределение значений]
[Примечание № 2: мне нужно wps храниться таким образом, потому что иногда мне может понадобиться всего три обои, не обязательно в числовом порядке]

2 ответа

Решение

Передача! Num! значение переменной FOR:-)

for %%N in (!num!) do echo Wallpaper %%g is #%%N - Title: "!%%N!"

Несколько дополнительных указателей:

  • Как написано, ваша команда DIR включает в себя папки. Вам нужно добавить /A-D вариант

    dir C:\Wallpapers /a:-h-s-d /b /s

  • Ваши числовые имена переменных работают в существующем коде. Но у вас будут припадки, если вы когда-нибудь попытаетесь получить к ним доступ, используя обычное расширение, потому что %1% будет расширен как 1-й пакетный аргумент вместо переменной окружения. В общем случае вам не следует начинать переменную среды с числа. Вы можете использовать:

    set wp!ind!=%%g
    ...
    echo Wallpaper %%g is #!num! - Title: "!wp%%N!

  • Вы можете сделать свой массив 0 на основе увеличения вашего счетчика в нижней части цикла, а не в верхней части. Тогда вам не нужно добавлять один к вашему случайному числу. (Этот совет тривиален. Больше вопрос стиля.)

  • Вам не нужны оба "tokens=*" а также "delims=", Я рекомендую последнее. "delims=" сохранит всю строку. tokens=* сохранит всю строку после удаления начальных пробелов и табуляции. Имя файла может начинаться с пробелов.

  • Ваш код потерпит неудачу, если любое из имен файлов содержит ! персонажи. Восклицание будет искажено при расширении %%g из-за задержки расширения. Это довольно легко исправить, включив отложенное расширение и используя переменную FOR для передачи значения через барьер ENDLOCAL.

Вот код со всеми рекомендациями на месте

@echo off
setlocal disableDelayedExpansion
set "wps=1 2 3 4"
set /a ind = 0

for /f "tokens=* delims=" %%g in ('dir C:\Wallpapers /a:-h-s-d /b /s') do (
  setlocal enableDelayedExpansion
  for %%N in (!ind!) do (
    endlocal
    set "wp%%N=%%g"
  )
  set /a ind += 1
)

setlocal enableDelayedExpansion
for %%g in (%wps%) do (
  set /a "num = (((!random! & 1) * 1073741824) + (!random! * 32768) + !random!) %% %ind%"
  for %%N in (!num!) do echo Wallpaper %%g is #%%N - Title: "!wp%%N!"
)

Вы можете использовать другой FOR, как предложил dbenham, или вы можете использовать CALL

call echo Wallpaper %%g is #!num! - Title: "%%!num!%%"

CALL расширяет строку во второй раз, но во втором повторении строки работает только процентное расширение, ни задержанное, ни расширение цикла FOR.

РЕДАКТИРОВАТЬ: Это работает, только если содержание Num не начинается с числа.

Но вы могли бы использовать cmd /c развернуть во второй раз, затем он работает также с числовыми именами.

cmd /c echo Wallpaper %%g is #!num! - Title: "%%!num!%%"
Другие вопросы по тегам