M y    b r a i n    h u r t s  !                                           w e                 r e a l l y                 t h i n k                   w h a t                y o u             k n o w

15 April 2010

Running a command recursively on all files in a directory tree

Windows solution
Here is a script which calls mplayer on every file in a directory including subfolders:

The script will work on dirs containing spaces and non-ascii characters since all file names are converted to short dos names (via the `~s` modifier).
  set mplayer=z:\path_to_mplayer\mplayer.exe
  for /f "delims=" %%f in ('dir /b /s "%cd%"') do (%mplayer% "%%~sf")
Linux bash solution
The bash shell solution is much easier to read than the windows one:
  for f in `find $cwd -type f -iname "*.mp3" `; do
    mplayer $f

A Better Solution

An alternative solution for both Windows and Linux would be to create a playlist file first, and then run a single mplayer instance with the -playlist switch:
Linux bash
  find $pwd -type f -iname "*.mp3" > /tmp/allfiles.m3u
  mplayer -playlist /tmp/allfiles.m3u
Windows Batch
  set mplayer=z:\path_to_mplayer\mplayer.exe
  set playlist=%TEMP%/mp3playlist.m3u
  dir /b /s "%cd%" | find /I ".mp3" > "%playlist%"
  %mplayer% -playlist "%playlist%"
Shortest solution
  mplayer $(find . -iname "*.mp3")


  1. what about:
    find . -iname "*.mp3" -exec mplayer {} \;

  2. 2spen:
    just like the `for each` solution `-exec` will start a new instance of mplayer for each file, which might or might not be what is desired.

    The playlist-based solution will simply feed the playlist to a single mplayer instance which is probably better in most cases.