Search code examples
shellm3u

Create a "Recently Added Albums" m3u playlist


I am trying to create a playlist that is the same idea as a "Recently Added Albums" playlist that you usually see in iTunes but using a $NUM_OF_DAYS_BEFORE parameter.

I've used most ideas from this post: How to recursively find and list the latest modified files in a directory with subdirectories and times?

I've created a script that I can run with the following params:

create_m3u /dir_root/with/mp3s 60

where $1 is the directory that is the root of my mp3s (that have folders within it that also have mp3s) where $2 is the number of days backwards from today that I'd like to create a m3u playlist file.

The main part of the script is this command:

find $1 -type f -iregex '.*\.mp3' -mtime -$2 -exec stat --format '%Y %y %n' {} \; | \
sort -n | \
cut -d' ' -f5- | \
sed -e 's/^/\./' 

Now my problem is, the above command up to and including the

cut d' ' -f5-

part gives me this type of output:

....
./RATKING - So It Goes - 2014 [V0]/09. Protein.mp3
./RATKING - So It Goes - 2014 [V0]/08. Puerto Rican Judo.mp3
./RATKING - So It Goes - 2014 [V0]/02. Canal.mp3
./RATKING - So It Goes - 2014 [V0]/05. Remove Ya.mp3
./RATKING - So It Goes - 2014 [V0]/04. So Sick Stories.mp3
./RATKING - So It Goes - 2014 [V0]/06. Eat.mp3
./RATKING - So It Goes - 2014 [V0]/03. Snow Beach.mp3
./RATKING - So It Goes - 2014 [V0]/07. So It Goes.mp3
./RATKING - So It Goes - 2014 [V0]/01. _.mp3
./RATKING - So It Goes - 2014 [V0]/10. Bug Fights.mp3
./RATKING - So It Goes - 2014 [V0]/11. Take.mp3
./Aesop Rock - The Blob (2014) [MP3 320]/01 The Blob.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/06 - Requiem.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/08 - Riot In My Brain!!.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/10 - Can't Let It Go.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/03 - Battling Voices From Beyond.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/02 - Meepy Morp.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/07 - Meepy Morp (Reprise).mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/09 - 7 SKIES H3 (Main Theme).mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/05 - Metamorphosis.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/04 - In A Dream.mp3
./The Flaming Lips - 7 Skies H3 (2014) [V0]/01 - 7 SKIES H3 (Can't Shut Off My Head).mp3
./G. Love & Special Sauce - 2014 - Sugar/14 - Bad Girl Baby Blues.mp3
./G. Love & Special Sauce - 2014 - Sugar/06 - Sugar.mp3
./G. Love & Special Sauce - 2014 - Sugar/10 - Windshield Wipers.mp3
./G. Love & Special Sauce - 2014 - Sugar/02 - Nite Life.mp3
./G. Love & Special Sauce - 2014 - Sugar/09 - One Night Romance.mp3
./G. Love & Special Sauce - 2014 - Sugar/03 - Good Life.mp3
./G. Love & Special Sauce - 2014 - Sugar/04 - Nothing Else Quite Like Home.mp3
./G. Love & Special Sauce - 2014 - Sugar/05 - Smokin Blues.mp3
./G. Love & Special Sauce - 2014 - Sugar/08 - Saturday Night.mp3
./G. Love & Special Sauce - 2014 - Sugar/13 - Run For Me.mp3
./G. Love & Special Sauce - 2014 - Sugar/07 - Weekend Dance #2.mp3
./G. Love & Special Sauce - 2014 - Sugar/12 - Too Much Month.mp3
./G. Love & Special Sauce - 2014 - Sugar/01 - Come Up Man.mp3
./G. Love & Special Sauce - 2014 - Sugar/11 - Cheating Heart.mp3

which is the way I want it (partially) - sorted by date when the album was added to the filesystem/PC. But what I additionally want is to have each album sorted by song number 01, 02, 03, 04... from each folder/album and not unordered numbers as seen above.

Does anyone have any advice on how I can do this differently so I can get the desired result?


Solution

  • Your original command has some redundancies - the question you linked requires the date in the output, whereas you don't, so you can skip some of the fields being outputted by stat. You can also skip stat by using find -printf. This should work (partly untested, sorry):

    find $1 -type f -iregex '.*\.mp3' -mtime -$2 --printf "%T@~.%h~%f\n" |\
    sort -t~ -nk1 -nk3 |\
    cut -d~ -f2- |\
    tr '~' '/'
    

    The find finds the same files, then prints out in the following format:

    [modified date in seconds since Unix epoch]~.[file directory]~[filename]
    ex:
    1234512345~./RATKING - So It Goes - 2014 [V0]~09. Protein.mp3
    

    We then sort firstly by the date, and secondly by the filename (both numerically, and using ~ as the field separator). Finally we strip off the date field, then replace the remaining ~ with a forward slash to give the full file path.

    Note: this will work only if your files all have the track number at the beginning of the filename, and also will not give the correct results for any file with a ~ anywhere in the file path (directory or filename). It was not chosen for any special reason, you can replace it with a more suitable character if necessary. The character replacement is required (as opposed to using forward slash as the sort delimiter) as (I assume!) the level of subdirectory that each file is in could potentially vary.