1

I have a main directory with hundreds of subdirectories, each containing one or more .cue files.

Main Directory
|
+---Subdirectory1
|       .cue1
|       .cue2
|
+---Subdirectory2
|       .cue1
|
+---etc.

I need a batch file which I can run in Main Directory, and will create a .m3u file in each subdirectory. The .m3u file should be named matching its parent directory name, with content listing each .cue file it shares that parent with, but as a relative path.

I found this script online:

rem Execute it in the directory which includes music files
rem It requires one argument which will become created m3u playlist file's name
for %%i in (*.mp3,*.mp4,*.m4a,*.wma,*.wav) do echo %cd%\%%i >> %1.m3u

I know enough to modify (*.mp3,*.mp4,*.m4a,*.wma,*.wav) to (*.cue) and it works if I put it into a subdirectory, but the .m3u it produces is nameless, and the paths inside it are absolute. (I can actually work with the absolute paths to the .cue files if making them relative is impossible, but it would take a long time to run this in every directory and rename the m3us as I went.)

Any help would be appreciated.

Mofi
  • 46,139
  • 17
  • 80
  • 143

1 Answers1

2

This task can be done on NTFS drives returning a list of file names sorted by name with:

@echo off
for /R "%~dp0" %%I in (*.cue) do for %%J in ("%%~dpI.") do echo %%~nxI>>"%%~dpI%%~nxJ.m3u"

The following batch code is better for FAT16, FAT32 and exFAT drives to get the *.cue file names written ordered by name into the *.m3u files.

@echo off
for /F "eol=| delims=" %%I in ('dir "%~dp0*.cue" /A-D-H /B /ON /S 2^>nul') do for %%J in ("%%~dpI.") do echo %%~nxI>>"%%~dpI%%~nxJ.m3u"

The batch file should be stored in Main Directory. Otherwise %~dp0 referencing the drive and path of the batch file ending always with \ must be replaced by full path of Main Directory ending also with a backslash.

The outer FOR processes all non-hidden full qualified *.cue file names (drive + path + name + extension) found recursively in the specified directory and all its subdirectories. The inner FOR runs always just once for every file name to get from full qualified file path of current file the name of the directory containing this file to name the *.m3u file like the directory.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /? ... explains %~dp0 - drive and path of argument 0 which is the full qualified path of the batch file.
  • dir /?
  • echo /?
  • for /?

Read the Microsoft article about Using command redirection operators for an explanation of >> and 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line running DIR to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background with %ComSpec% /c and the command line within ' appended as additional arguments.

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • Why would the file system make any difference in the script? – jwdonahue Feb 04 '20 at 09:09
  • Please read my answer on [In which order does command COPY copy files from source to destination?](https://stackoverflow.com/a/44205461/3074564) To get the files ordered by name written into the *.m3u file on FAT based file systems, it is necessary to explicitly run command __DIR__ with option `/ON` to get the list ordered by name because of the FAT file system does not return the list ordered by name. __DIR__ without `/ON` lists the entries of a directory in the order as returned by the file system. __FOR__ processes the file names always as returned by the file system one after the other. – Mofi Feb 04 '20 at 14:34
  • This is no problem in this case with writing into a directory a *.m3u file resulting in updating the file table while processing one *.cue file after the other because of the file extensions are different and so the file table updates do not matter. But it would be a problem on NTFS and especially on FAT drives if the commands executed on each iteration of the loop changes those entries in file table which are matched by the wildcard pattern. Then it would be really necessary to use the method with __FOR /F__ and __DIR__ to process a captured list of names not changing during the loop runs. – Mofi Feb 04 '20 at 14:40