bash scripting: playlist maker

Summary

Decided to take another stab at converting small programs to bash. This time, the python playlist maker was updated to bash and greatly simplified, no longer need to do sketchy recursions.

For those who want to dive right in, the script is included here (or see the end of the article for full script):

bash playlist maker

A little bit ago, I posted a short python script to automatically create music playlists. It was a bit clunky and relied on a rather sketchy recursion implementation, i.e. there was no real base case (it just assumed you didn't have an infinitely large directory). I wanted to fix this and transfer the script to a more general language that could be used on most computers. So I turned to bash scripting. Terminal (Unix/OSX), cygwin (Windows), and other shell environments will run bash scripts without any trouble and no extra libraries or software is needed besides the base OS (or in the case of cygwin, the base install).

The script itself is rather simple, its core components is only around eight lines of code, the rest is just options for the user. I have a short yes/no function to standardize asking for input and then change the internal file separator to allow compatibility for people who like to litter spaces throughout their filenames and folders. The directory is requested from the user; I would suggest that you put the script in the root folder and then just type a dot to indicate use of the current directory.

Bash
  1. #!/bin/bash
  2. # biafra ahanonu
  3. # updated: 2013.03.23
  4. # script to make playlists
  5.  
  6. # Yes/No function
  7. getYesNo(){
  8.         select terminateSignal in "Yes" "No"
  9.         do
  10.                 case $terminateSignal in
  11.                         "Yes" )
  12.                                 return 1;;
  13.                         "No" )
  14.                                 return 0;;
  15.                 esac
  16.         done   
  17. }
  18.  
  19. # Change file separator to allow use of files with spaces
  20. oldIFS=$IFS
  21. IFS=$(echo -en "\n\b")
  22.  
  23. # Ask user for directory
  24. echo "Directory? "
  25. read userDir
  26. echo $userDir
  27.  

Next, the user is asked to delete old .m3u files and then choose the audio file extensions that their library consist of. Any new extensions are requested are added to the old one and then I use sed to convert the list into a form that is readily interpreted by find.

Bash
  1.  
  2. # Ask to remove old .m3u files
  3. echo "Remove old .m3u files? "
  4. getYesNo
  5. response=$?
  6. if [[ $response == 1 ]]; then
  7.         find . -regex '.*\.m3u' -delete
  8. fi
  9.  
  10. # Get file extensions to search for
  11. fileExt='mp3,wma,aac,flac,ogg,m4a,m4p,wav'
  12. echo 'Current search file extensions: '$fileExt
  13. echo "Add more extensions? "
  14. getYesNo
  15. response=$?
  16. if [[ $response == 1 ]]; then
  17.         echo "List extensions, separated by a comma: "
  18.         read fileExtUser
  19.         fileExt=$fileExt$fileExtUser
  20. fi
  21.  
  22. # Convert to find ready form
  23. fileExt=$(echo $fileExt | sed 's/,/\\|/g')
  24.  

find allows recursive searching for files matching a regular expression within a folder tree. It is much more robust and elegantly implemented than my use of python and is compatible with all the common operating systems. I loop over all folders in a directory and find their files recursively. The folder name is removed from the path and then all the files are saved to a .m3u file in that folder in a single line. neato!

Bash
  1.  
  2. # Loop over all folders in directory and add playlist to the root folder
  3. for folder in $(ls -d */); do
  4.         playlistName=$(echo $folder | sed 's/\///g;s/ /_/g')
  5.         folderName=$(echo $folder | sed 's/\///g')
  6.         find "$folder" -regex $fileExt | sed "s/${folderName}\///g" > $folder$playlistName".m3u"
  7.         echo $playlistName".m3u"
  8. done
  9.  
  10. # Return file separator to default
  11. IFS=$oldIFS

While different error handling and other code could be added to flesh this out, I think the current implementation is a nice and cheap way to make playlist in an entire library very quickly without installing any additional software. Adding extended M3U directives could be included, but normally music players read the information directly from the files after the playlist has loaded and I thus found the added expense and complexity not worth the effort.

The script is compatible with more obscure symbols that python trips over and sed, grep, and others can be used to further modify output via pipping, much easier than doing it all in python. Overall a fun little exercise in make a script more useful by taking advantage of both bash scripting and pre-existing programs.

download playlistMaker.sh

Bash
  1. #!/bin/bash
  2. # biafra ahanonu
  3. # updated: 2013.03.23
  4. # script to make playlists
  5.  
  6. # Yes/No function
  7. getYesNo(){
  8.         select terminateSignal in "Yes" "No"
  9.         do
  10.                 case $terminateSignal in
  11.                         "Yes" )
  12.                                 return 1;;
  13.                         "No" )
  14.                                 return 0;;
  15.                 esac
  16.         done   
  17. }
  18.  
  19. # Change file separator to allow use of files with spaces
  20. oldIFS=$IFS
  21. IFS=$(echo -en "\n\b")
  22.  
  23. # Ask user for directory
  24. echo "Directory? "
  25. read userDir
  26. echo $userDir
  27. cd $userDir  
  28.  
  29. # Ask to remove old .m3u files
  30. echo "Remove old .m3u files? "
  31. getYesNo
  32. response=$?
  33. if [[ $response == 1 ]]; then
  34.         find . -regex '.*\.m3u' -delete
  35. fi
  36.  
  37. # Get file extensions to search for
  38. fileExt='mp3,wma,aac,flac,ogg,m4a,m4p,wav'
  39. echo 'Current search file extensions: '$fileExt
  40. echo "Add more extensions? "
  41. getYesNo
  42. response=$?
  43. if [[ $response == 1 ]]; then
  44.         echo "List extensions, separated by a comma: "
  45.         read fileExtUser
  46.         fileExt=$fileExt$fileExtUser
  47. fi
  48.  
  49. # Convert to find ready form
  50. fileExt=$(echo $fileExt | sed 's/,/\\|/g')
  51. fileExt='.*\.\('$fileExt'\)'
  52.  
  53. # Loop over all folders in directory and add playlist to the root folder
  54. for folder in $(ls -d */); do
  55.         playlistName=$(echo $folder | sed 's/\///g;s/ /_/g')
  56.         folderName=$(echo $folder | sed 's/\///g')
  57.         find "$folder" -regex $fileExt | sed "s/${folderName}\///g" > $folder$playlistName".m3u"
  58.         echo $playlistName".m3u"
  59. done
  60.  
  61. # Return file separator to default
  62. IFS=$oldIFS

-biafra
bahanonu [at] alum.mit.edu

additional articles to journey through:

quicklinks github
12 august 2012 | programming

quicklinks is a new homepage for those looking for efficiency over lavish use of big buttons commonly seen in Firefox, Opera and other brow[...]ser's homepages. As quicklinks is still a little rough around the edges and needs to be updated, I've added it to GitHub to allow me to update it easier.

bio42: notes
12 may 2013 | teaching

While teaching bio42 (cell biology and animal physiology) I created weekly notes to help students in my section study and focus on the impo[...]rtant materials presented in the class. I built off of the latex boilerplate that I have been improving over time to create weekly notes. This highlights why I love LaTeX so much, especially for larger projects that are heavily linked—it allows easy annotation, indexing, creation of new document styles, and other related processes rapidly and consistently. Plus, separating content and style is always a plus and images stay uncoupled from a propriety source (e.g. Word files).

I really love the resulting notes and student feedback was quite positive. I thought sharing them might be useful for others in the future. The source latex files and raw images can be sent upon request (I'm considering making a Github repository in the future). I'll briefly talk about the document below and certain decisions that were made to get it to its current state.

state of sbsa: a review of 2017 and thoughts on future directions
04 june 2017 | sbsa

I spent the past year leading the Stanford Biosciences Student Association (SBSA) as President. This post consist of the letter to the comm[...]unity I sent out at the end of my term giving some highlights of the past year, those who have helped out, and thoughts on future directions.

from the archives: declaration of independence, internet edition
11 july 2013 | america

A revised Declaration of Independence I did awhile ago (i.e. high school) for a writing class. It is slightly a mockery of the style of wri[...]ting sometimes used back then, e.g. finding unnecessarily complicated ways of saying a simple concept; long, ponderous sentences; and an abuse of the Capital.

©2006-2025 | Site created & coded by Biafra Ahanonu | Updated 21 October 2024
biafra ahanonu