0

I have a CSV file with a list of several hundred music tracks and would like extract 100 pieces randomly. I am completely new to bacth scripting.

The creation of the table is correct but I would like to be able to make it random and not duplicated.

The second FOR (in :RANDOMIZE) doesn't echo anything

@ECHO OFF

setlocal enabledelayedexpansion

set _total=0
set _max=100

for /f "skip=1 tokens=11 usebackq delims=;" %%I in ("playlist.csv") do (
    set _filepath=%%~I
    set _ext=%%~xI

    if "!_ext!"==".flac" CALL :ADDARRAY
    if "!_ext!"==".mp3" CALL :ADDARRAY
)

:RANDOMIZE
for %%a in (%_array%) do (
    set /A _total+=1
    echo %%a
    if "!_total!"=="!max!" @goto :eof
)

:ADDARRAY
set /A _cpt+=1
set _array[!_cpt!]=!_filepath!
@goto :eof
  • 1
    There is no variable named `%_array%`, that's why the `for %%a` loop doesn't iterate. The loop should actually be this: `for /F "tokens=1* delims==" %%A in ('set _array[') do (`, then use `%%B` in the loop body. Alternatively, use this loop: `for /L %%B in (1,1,%_max%) do (` (also using `%%B` then). Moreover, there is no variable called `!max!`, it's `!_max!`. Although this still doesn't return random values… – aschipfl Sep 17 '20 at 15:49
  • Thanks aschipfl for your answer Worked like a charm :) Do you know how I can randomize it ? –  Sep 17 '20 at 15:56
  • You're welcome, though this isn't an answer but just a comment as the essential part of randomisation is missing, which is not that trivial, particularly when you want to avoid duplicates. You could try to use the search feature of this site, with the search term `[batch-file] random without duplicates`, for instance. If you don't care about duplicates, try `set /A "RND=!RANDOM!%%%_max%+1" & echo !RND!` in the loop… – aschipfl Sep 17 '20 at 17:11

2 Answers2

0

Here is a way to do it in PowerShell. If you are on a supported Windows system, PowerShell will be available. This is easily run from cmd.exe as well.

$songs = Import-Csv -Path 'C:\src\t\playlist.csv'
$chosen = 0..$songs.Count | Get-Random -Count 5
foreach ($c in $chosen) { $songs[$c] }

If you can only run from cmd.exe, use this.

@powershell -NoLogo -NoProfile -Command ^
    "$songs = Import-Csv -Path 'C:\src\t\playlist.csv';" ^
    "$chosen = 0..$songs.Count | Get-Random -Count 5;" ^
    "foreach ($c in $chosen) { $songs[$c] }"
lit
  • 14,456
  • 10
  • 65
  • 119
0

Finally I found a good work around thanks to Aacini

Here is my code it works fine

rem -------
rem | UT8 |
rem -------

chcp 65001

cls

@ECHO OFF

setlocal EnableDelayedExpansion

rem ---- ENTREE UTILISATEUR POUR LE MAXIMUM DE MORCEAUX A PRENDRE (Illimité si aucune saisie) ----
set /p "_maximum=Nombre de morceaux à récupérer : "

cls

rem ---- VARIABLES ----
set _iFLAC=0
set _iMP3=0
set _total=0
set _index=0
set _cpt=0
set ""="

rem -----------------------------------------------------------------------------------------------
rem | Alimentation de la table à partir du fichier csv : tokens=11 -> 11eme colonne du fichier csv |
rem | uniquement s'il s'agit d'un fichier FLAC ou MP3                                              |
rem | dans la limite du nombre maximum de morceaux saisi par l'utilisateur                         |
rem -----------------------------------------------------------------------------------------------

for /f "skip=1 tokens=11 usebackq delims=;" %%I in ("playlist.csv") do (
    set _filepath=%%~I
    set _ext=%%~xI

    if "!_ext!"==".flac" CALL :ADDARRAY
    if "!_ext!"==".mp3" CALL :ADDARRAY
)

rem ---- Si l'utilisateur n'a rien saisi le maximum est la nombre d'entrée total ----
IF NOT DEFINED _maximum set _maximum=!_index!

echo ---------------------------------------------------------------------------
echo                  NOMBRE DE MORCEAUX A TRAITER : !_maximum!
echo ---------------------------------------------------------------------------

for /L %%B in (1,1,%_maximum%) do (
    call :getRandomElem i=
    set _array[!i!]=0
)

echo LISTE final
echo -----------
for /L %%A in (1,1,%_maximum%) do (
    echo !_final[%%A]!|find "flac" >nul
    if errorlevel 1 (CALL :MP3) else (CALL :FLAC)
    echo !_final[%%A]!
    echo/
)

:END
echo ---------------
echo FLAC : !_iFLAC!
echo MP3 : !_iMP3!
echo TOTAL : !_total!
@goto :eof

:ADDARRAY
set _array[!_index!]=!_filepath!
set /A _index+=1
@goto :eof

:getRandomElem i=
set /A i = _index * %random% / 32768 + 1
if !_array[%i%]! equ 0 goto getRandomElem
set /A _cpt+=1
set _final[!_cpt!]=!_array[%i%]!
exit /B

:FLAC
echo FICHIER FLAC !_array[%%B]!
set /A _iFLAC+=1
set /A _total+=1
@goto :eof

:MP3
echo FICHIER MP3 !_array[%%B]!
set /A _iMP3+=1
set /A _total+=1
@goto :eof
Dharman
  • 30,962
  • 25
  • 85
  • 135