我不擅长编写任何类型的批处理脚本,所以我从其他地方混合了这个解决方案。它可以完成工作;将文件从一个目录(及其所有子目录)复制到另一个目录,似乎是随机的。
但是它无法复制全部文件,我不确定为什么。如果我将其设置为 10,它可能会返回 7 或 8。有什么想法吗?谢谢。
@echo off
setlocal
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir "D:\Users\...\Music" /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
:: Copy number random files, doesn't get them all though?
for /l %%N in (1 1 100) do call :copyRandomFile
:: Delete the temp file
del "%tempFile%"
exit /b
:copyRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do xcopy "%%B" "D:\Users\...\Playlists\Random"
exit /b
编辑:抱歉,需要进一步解释:我有一个装满音乐的文件夹(虽然根据艺术家等分类在不同的子目录中),我想随机选择 100 个文件并将它们复制到我的输出文件夹,以便基本上有一个 100 首歌曲的随机播放列表可以传输到 mp3 播放器上。上面的代码可以做到这一点,但由于某种原因,它没有复制所需数量的文件。
答案1
是否必须是 Windows 批处理?如果不是,在此主题中是一个 Powershell 解决方案以及一些批处理代码。
电源外壳:
Get-ChildItem SomeFolder | Get-Random -Count $x | Copy-Item -Destination SomeOtherFolder
假设您从文件所在的文件夹运行脚本。替换某个文件夹包含文件路径和其他文件夹并输入您想要的目的地。
进一步解释一下:
Get-ChildItem -Path C:\path\to\directory # Lists content of the directory
# To get subfolders you have to add -Recurse
# to limit this only to files add -Files
Get-Random -Count $x # Selects x random items from previous command.
# You have to define $x beforehand
Copy-Item -Destination C:\path\to\destination # Copies the random selected files to
# your defined destination
您可以将此代码复制到文本文件中,另存为 *.ps1,然后右键单击使用 powershell 运行。
我可能会让 powershell 抛出一个错误,例如无法加载脚本,因为此系统已禁用脚本执行。
如果是这种情况,你必须以管理员身份启动 powershell 并运行Set-ExecutionPolicy RemoteSigned
笔记:
我在测试时发现的另一个缺点是Get-Random
您可能会多次获得相同的物品。证明
为了防止这种情况,我推荐该Get-Unique
命令。
答案2
@echo off && Setlocal EnableDelayedExpansion
set "_source=D:\Users\%YourUserName%\Music"
set "_target=D:\Users\%YourUserName%\Playlists\Random"
>nul 2>&1 cd /d "!_source!" || =;( endlocal & goto :eof );=
for /f usebackq^tokens^=1-2*delims^=^:^eol^=^| %%G in =;(`
dir /b /s /a:-d ^| "%__AppDir__%findstr.exe" /n "^"
`);= do set "_%%~G=%%~H:%%~I" && set "_max=%%~G"
for /l %%L in =;(0001 0001 0100);= do for /f usebackq %%x in =;(`
set /a _rage_randon_number^=!random! * %_max% / 32768 + 1
`);= do echo/!_ran!|%__AppDir__%find.exe "_%%~x" >nul || =;(
set "_ran=_%%~x,!_ran!" && set /a "_cnt=!_cnt! +1 +0"
);= && if !_cnt! equ 10 goto %:^)
%:^)
2>&1 =;(
cd /d "!_target!" && del /q /f /a: "*.mp3" || mkDir "%_target%"
);= 1>nul & cd /d "!_source!"
for %%i in =;(!_ran!);= do set /p "'=Copyng: "!%%~i!"" <nul & =;(
>nul copy "!%%~i!" "%_target%" && echo/Done^^! || echo/Error^^!
);=
endlocal
1.输入文件所在的文件夹并findstr
循环列出:
cd /d "!_source!" // "D:\Users\%UserName%\Music"
for /f ...(`dir /b /s /a:-d ^| findstr.exe /n "^" )do...
2.使用循环的输出组成定义变量的命令_number=path
并定义max
文件数量:
for...)do set "_%%~G=%%~H:%%~I" && set "_max=%%~G"
3.创建一个变量,随机、不重复地保存包含路径的变量的数量:
...)do echo/!_ran!|find "_%%~x" 1>nul || set "_ran=_%%~x,!_ran!" ...
4.限制循环并set _ran=_new-value,!_ran!
计数器随着变量中每添加一个新项而增加_ran
,并将所选文件限制为 10 个:
set "_ran=_%%~x,!_ran!" && set /a "_cnt=!_cnt! +1 +0") && if !_cnt! equ 10 goto %:^)
5.输入您的目标文件夹并删除上次运行中复制的 mp3,如果您的文件夹尚不存在,请创建它:
cd /d "%_target%" && del /q /f /a: "*.mp3" || mkDir "%_target%"
6.当变量中达到 10 个不重复的数字时,退出循环并使用保存的数字!_ran!
创作copy command
随机抽取 10 个文件:
for %%i in (!_ran!)do ... copy "!%%~i!" "%_target% ...
其他资源: