Shared publicly  - 
 
I have a scripting question. If you don't care about this stuff, skip this post

I have all my music in a folder called /iTunes/Music. When I add files to iTunes, it put them inside this folder, so it looks like this: /iTunes/Music/artist/album/track

Pretty standard stuff, I believe.

I recently eliminated about 10GB of music from my iTunes library, but stupidly left those files inside /iTunes/Music. I have the entire thing backed up and pristine on an external drive, so I don't need to keep that music in that folder.

Here's my question: I want to write a script that will compare my iTunes library to the contents of /iTunes/Music, identify files that are in /iTunes/Music but not the iTunes Library file,and  move them to a new folder (probably in /tmp) so I can take a look, then delete them.

I think I would have a script put the output of ls (I don't recall the flags off the top of my head) into a file, then diff that file with the contents of Library.xml, and move the resulting files into a new directory.

Is that how you'd do it, Person Who Does Programing For Real? Would you just do a .sh thing from the command line?

And before I try to figure out how to do this (it's been 15 years at least since I did any shell scripting), does anyone know if an AppleScript already exists to do this?

Thanks in advance for being my braintrust.
83
6
joe bieb's profile photoJohn Meagher's profile photoV Hanes's profile photoGastón Alegre Stotzer's profile photo
140 comments
 
Just use rsync. There's flags that allow you to create what's essentially a diff-copy.
 
Python with OS.walk is where I would likely start myself. Doesn't sound difficult really. Except getting capitalization correct on my cell phone to describe it
 
Rsync requires the same directory structure iirc, not sure if that is the case here from the description
 
+Thomas Jones +Piotr Kucharski No, rsync keeps two different folders in sync.  Wil only has one, but a partial record of its contents.  The approach he suggests (create listing, compare to iTunes's XML record) is almost definitely the correct one; the main thing to determine is whether someone has already done this.  I suspect that Doug's Scripts has something.
 
That's about how I'd do it. I'd use a shell or python script more or less exactly how you've described, which you could run whenever you felt like, or create a regularly scheduled event which creates a "Heres-what-I-moved.txt" file, or similar, for output.

Not being an apple guy I can't help with the AppleScript part, but I'm sure many others will!
 
I'd geek out and create a .text file from the folder and compare it to an Excel file from iTunes. Simple outer join in Access. 
 
If I recall, iTunes has an option to organize your music for you or to leave the file system intact.  I'd copy the files you want to a storage drive and map it to some cute letter like M for music or D for Data or S for storage depending on your preferences, then set iTunes to resync with your library.  At that point you could write a script in whatever scripting language that you prefer to organize them for non iTunes use.  This allows you to share them with yourself over the internet etc.  One of the things I hate most is to have the same set of songs in 2 or 3 different locations/devices to accomodate for today's multiple device users.  For example, I wrote a script that builds a web page with a login ID/password that allows me to log in from my phone and play songs and movies through the internet.  Hope this helps.
 
I do a lot of UNIX scripting for a living, and your approach sounds right.  I've never done this sort of thing in the Apple universe, but I gather the latest Apple OS's have a lot of UNIX foundation underneath them, so I expect the approach would be the same.  The only real problem I can see with using diff is ensuring that format of the file created by ls and the format of the Library.xml file are the same.  In UNIX, i'd probably use an awk script to parse the Library.xml file so it outputs lines that match the ls file, assuming they aren't already the same.  For diff to work, the files essentially have to be identical in format.  The other issue you might have with diff (I am making UNIX assumptions here as well) is the order of entries in the two files.  Diff compares line by line, so if the lines are in a different order, it will find that line 1 in the first file doesn't match line 1 in the 2nd file, and move on, even though it might match line 2.  If order is an issue, then you can either use the sort command to sort one of the files, or you can use a script that reads a line from the ls file, then scans the entire Library.xml file for a match ... that will potentially chew up processor cycles, but unless you have a collection of billions of files, it won't be prohibitively slow.

Feel free to direct message me if you have questions :)
 
The simplest approach is to use the diff command to compare two subdirectories: diff -r bar foo gives me:
Only in foo/baz: geek.txt
Only in foo/baz: sundry.txt
Only in bar: shae.txt

and the directory structure looks like this:
.
├── bar
│   ├── baz
│   ├── shae.txt
│   └── wil.txt
└── foo
    ├── baz
    │   ├── geek.txt
    │   └── sundry.txt
    └── wil.txt

http://hpaste.org/76343 in case the ascii art fails horribly
 
I'm not a Mac user, so I can't speak to the AppleScript question, but to answer the other question (as an ex-Software Engineer) yes, I'd write a shell script. I don't know if I'd use diff since the formatting of the ls output and the Library.xml file would be markedly different and you'd have to deal with that. It's possible but my personal preference would be not to deal with it.

Since this is just a one-time script, I wouldn't worry too much about making it elegant and just write something that works. You could just use ls -R to loop through all the files in the directory then check for its presence in the Library.xml file; if it's there do nothing and if it isn't move the file to your temp directory and append it to a summary file (assuming you want to track what the script is doing).

That would be my approach because it's simple - string matching in Library.xml is the most complex part and it's not that hard - and it can be written/debuged quickly, but there are probably Linux gurus out there that could give you a more elegant/efficient solution :)
 
Programatically you're correct in how you want to go about it.  Getting the list of music, then compare it to the library.xml and moving the difference.

If you were on Windows I'd be able to write it out in batch pretty quickly... sadly, my Mac scripting skills are sorely lacking
 
You're looking to write a script that will actually delete from disk (or move from their current location) the files that are deleted from the library.xml?

I don't know the format of the library.xml, but you probably want to do something like

$ find /iTunes/Music > /tmp/on_disk_music
$ grep '/iTunes/Music' library.xml /tmp/in_library_music

double check that the files have the same sort of data (ie, that the the paths both start with '/' and the in_library_music doesn't have a bunch of preceding newlines, etc)

$ for file in $(cat /tmp/on_disk_music) ; do
 if ! grep -q $file /tmp/in_library_music 2>/dev/null ; then
  mv $file /tmp/backup/
  fi
done

This will have issues if more than one file has the same name and it won't preserve any of the artist/album/track path information.
 
There's always StackOverflow if you can't figure it out. 
 
I don't think this would necessarily need to be a script. You could write any program that would read a file name, compare it to the file in the other folder, and then copy whichever ones you want into a new folder. I think writing a script to do it would actually be more work than writing a program in Java or C#. Just my opinion though.
 
As mentioned, Python should have all you need for that. Parse the XML file, then walk the directories and see what differences there are.
 
Edit: Phil Smith above me has what looks to me like a good script.
I'd be inclined to go the quick and dirty .sh script route.
While regex is by no means a proper way to parse XML I think that you should be able to regex to find files in your library by getting lines of the format:
<key>Location</key><string>file://localhost/iTunes/Music/foo/bar/baz.m4p</string>
Once you have your list you can recursively check every file (using `ls -r` or `find -exec`) and move them if they aren't found in the list.
 
+Tyler Geffre Why would a script be more work? A script is an interpreted program, no more, no less. Given the command line utilities, it's probably less work than doing it in a program, unless you're already set up with those libraries.

/C++ programmer
//Rarely script
 
iTunes has an acton "Reorganize Library" in "File>Library>Organize Library" that might work for you. 
 
You would have marginally simpler logic (potentially useful if you're not totally confident) if you moved or copied all of the files to a temporary directory and then removed the ones that ARE in library.xml. That only requires you to parse one file, instead of two.

(And depending on the format of library.xml, you may be able to extract all of the file names with something as simple as grep)
 
I don't use iTunes, so I may be missing an idiosyncrasy of the program and/or its licensing, but if I was sitting on top of a pristine backup I would simply get on the computer and eliminate all related files and folders, then restore from backup whichever parts are desired.

Or is this not geeky enough?
 
Guy who knows something about mac internals here, I think with a little bit of sweat you could get this working using launchd and some bash, check this out: 

here is how launchd works (replace the action with the launch of a script):
http://stackoverflow.com/questions/1515730/is-there-a-command-like-watch-or-inotifywait-on-the-mac

the script could be some bash like this (replace echo "$file" with whatever you want to happen with those file names):
http://stackoverflow.com/questions/2435386/read-the-contents-of-a-directory-using-shell-script

also stackoverflow in general is pretty ripping.
 
+Terence Stigers - I think the issue at hand is deciding which parts are desired. There's a big bucket of files, some of which are registered with iTunes and some of which aren't (but all of which are presumably in his backups). He's trying to sort the wheat from the chaff.
 
Honestly, I'd probably just make a copy of my Library.xml file and use a text editor and some regex to get it down to a simple alphabetical list of file names - only takes a few minutes if you are clever.

Then you ought to be able to simply diff it against the directory listing.
 
Use rsync, you can have it listed what it's going to do. You can take that list and make a script of rm calls if you like, or have rsync do it. 
 
I'll add a second for the Doug's Scripts for iTunes "Music Folder Files Not Added" script.  Works like a charm.  I use it about once every 3 months to make sure I didn't accidentally remove-without-deleting.
 
The solution that already exists IS usually an excellent place to start. Nice find! :)
 
You can just do a for loop with ls as its input. This should (roughly) work (you'll need to replace $iTunesLibraryFile with the path to the file that iTunes stores its info in):  for artist in `ls /iTunes/Music`
do
   for album in `ls /iTunes/Music/${artist}`
   do
      for track in `ls /iTunes/Music/${artist}/${album}`
      do
         grep -q $track $iTunesLibraryFile
         if [ $? -ne 0 ]
         then
            mkdir -p /tmp/${artist}/${album}/${track}
            mv /iTunes/Music/${artist}/${album}/${track} /tmp/${artist}/${album}/${track}
         fi
      done
   done
done  
 
Hi Sean!  Sorry, I hadn't seen your post.  I'd just gotten through testing Phil's solution against mine to check they got the same result and posted my finding that his works.
 
+Adam Browning iTunes Music Library.xml stores location strings URL-encoded (space becomes %20, UTF-8 characters turn into 2-4 byte sequences), so at the very least you need to add urlencoding somewhere (unless Wils library is completely ASCII, in that case pseudo sed s/ /%20/g might be enough)
 
The script in Doug's Scripts mentioned above seems to do exactly what Wil asks for, with a small number of provisos:  it has false positives on SD or 720p HD versions of things where there is also a 1080p version present (iTunes seems to only include the highest-resolution version in the XML), and it mistakenly includes m4r ringtones.  If these cases are excluded, I think it does exactly the necessary.

Please consider throwing a few dollars Doug's way if you use it and find it useful.
 
Note : the shell script linked will probably throw false positives because the iTunes XML file uses URL-encoding of non-ASCII filenames, and indeed anything with spaces in it.
 
Ah, ok, thanks +Michael Gmelin; I've never used iTunes, and am not particularly familiar with the format of its config files. 
 
Funny, I would have just clicked to let iTunes scan the directory to add anything it didn't already have, then sort by date added and delete them again, removing from disk this time.  I'm sure it's way more CPU intensive and all, and doesn't show off any scripting chops, but it takes probably a total of six clicks and zero typing or coding.

Edit:  Also stands very little chance of destroying your library, given the encoding questions inside the library XML, file types that are or are not normally tracked inside iTunes, and so forth.  
 
For ~$40, Goodsync for Mac supports bidirectional synchronization. I use it for MS Windows but it looks like it will do that trick and then some.
 
I'm opening a feature request with Google; add an option "force people to read the thread before they comment".
 
Colm, I'll submit that to a friend who works at Google with the last name Buckley.  :-D  (Shoot, he works with YouTube, not Google+, though...)
 
+Wil Wheaton you don't need to do any scripting. Here's how it works:

1. In iTunes: Select all items in "Music" and drag them into a new playlist
2. Goto Finder/Explorer and drag the Music/ folder into your Libray (this will add the orphan files but not add duplicates).
3. In iTunes: Make a Smart Playlist and set type Music AND "not in playlist <playlist you crated in step 1>"
4. Review/delete entries in the new smart playlist

@console
 
I thought you meant "scripting" as in how to write a script for television or film.  I was going to tell you to keep your exposition short.
 
I have not read the other comments, but my first reaction off the top of my head is that I would not try to write scripts to play around with the iTunes source files directly. I had a very bad experience doing this when trying to be clever at migrating iPhoto from one machine to another, and lost most of the original photo files from a 3-4 year period.

If you do this, I would encourage you to make absolutely sure that you have a complete intact backup of your iTunes library -- your entire ~/Music directory -- and test it beforehand if possible by restoring it on another machine, or at least another account on the same machine.
 
I wouldn't bother comparing anything. Dump the itunes db entries with the file locations of the files you want, turn that list of valid files into a series of mv commands to move them all to a "keepthesefiles" folder.

Nuke everything and re-import those into itunes, thereby recreating their folder structure.

Lots of machine time, but super easy.
 
Wouldn't it be simpler to re-add all songs from the iTunes Folder back in iTunes, and re-delete it and check the delete from filesystem checkbox when re-deleting them?

And if you feel no so certain, make sure to make your Time Machine Backup before hand just in case you deleted something you didn't want to.
 
This is probably in vain, but…  seriously; there is an approximately perfect solution about 40 comments up.
 
I feel super nerdy right now. I feel like Wil Wheaton is personally asking me (and thousands of others I suppose) a scripting question. The Internet is an awesome thing.
 
If you find out, please share, I have the same problem
 
you could do a shell script, but I would recommend perl or python.  I haven't done it or seen it before, otherwise I'd point you to something.  I have done some complex shell scripting that turned out to be ridiculously easy in Perl, even though I didn't know ANY Perl at the time.   Python is probably even easier.
Scott T
 
Easy shell script.
 
probably already answered, but in perl or python, parse the library.xml and put the song file names into a hash table, then list the contents of the directory and check each file name against the hash table, if it doesn't exist in the library, move it to a temp directory.  
 
I fully expect the suggestions to continue right through the night.  Go on, get creative.  How long can this thread get?
 
I would do something like the following (actually had to dig into a few man pages and play around to get this, but it was fun.)  This is probably not as elegant as it could be, but it gets the job done (in my very limited tests anyway)

diff -l /dir1 /dir2 | sed -e "s/Only in dir1\/: /dir1\//g" | sed -e "a  /tmp" | xargs -n2 mv

replace dir1 and dir2 with the directories you are comparing.

What this is doing:
Diff only files in the two directories, replace "Only in dir1/: " with "dir1/" (which will result in things like dir1/foo.txt), append /tmp, then pipe that to xargs and tell xargs to use what's being sent to it in pairs to execute the mv command.  

IE: I'm translating "Only in dir1/: foo.txt" to mv dir1/foo.txt /tmp

One slight issue; if you have files in dir2 that aren't in dir1, it'll try to do "mv Only in dir2/: bar.txt /tmp".  If dir2 has some files that don't exist in dir1, then this won't work.  I recommend running a test on some dummy data (just set up a couple of dummy dirs with some files to make sure it appears to be working, and if you're really worried, replace that mv with cp)
 
Never used itunes, but sounds like a simple problem... get all those filenames (ls or rather find), grep that xml-file for each and (re)move if not found. :)
 
I won't rest until I see a version coded in INTERCAL.
 
Person Who Does Programming For Real just happens to be my actual legal name but, I don't do Apple and I don't know how an iTunes library works, sorry. This would be a trivial problem for me if it wasn't iTunes and Apple.
 
I would be a true programming proficient, had I but practised.
 
Three line version for the shell:

cd ~/Music/iTunes
cat iTunes\ Music\ Library.xml | grep Location | echo -e $(sed 's/\&#38;/\&/g; s/%/\\x/g') >/tmp/t
find "iTunes Music" -type f -exec sh -c 'fgrep -q "{}" /tmp/t || echo "{}"'  \;
 
+Colm Buckley Yeah, I completely forgot about the .xml thing.  I'd try not to parse an xml with a regex though, that can get ugly (as I'm sure you're aware).  I used to parse HTML for a living; libraries are your friends. +Phil Smith above's gist seems to have the right idea, but all that does is identify the files, not move them.
 
+Erin Kiser Parsing xml is eaiser than parsing html though. I wish the rules of xhtml were the original rules of html.
 
If you are going to parse XML, just use a PHP script and SimpleXML :) PHP even has great functions or reading/writing from the filesystem.
 
Yes. I'd use something that can parse the XML (perl w/libxml?) and grep the file locations against the output of a find .


/I hate perl, though (I forget it all the time!) so I'd grep the library XML file for all mp3/AAC files, do a cut/awk process job to get just the file names, THEN grep against the find output.
 
Assuming that you can parse the lists into just the filenames without any directory, the following python code should do what you want:

a = ..list of names from directory 1..
b = ..list of names from directory 2..

# Now the real fun..
a = set(a)
b = set(b)
onlyina = a.difference(b)  # only the files that are in list a
onlyinb = b.difference(a)  # only the files that are in list b

# you now have two sets that contain the differences and you
# can now operate on those
 
If you run into a programming brick wall and get frustrated, I believe you can cheat and get a cleanup by choosing a new (empty) iTunes folder and then organizing/consolidating your library.  It won't show you the leftover bits, but at least you'll have a squeaky clean iTunes folder and maintain your stunning coiffure.
 
I'd try creating an iTunes playlist that includes everything in the library, and export that as an m3u.  The m3u should be much easier work with than the iTunes xml file.

You can use rsync to "copy everything but this list of files".  Pass the m3u file (remove header if there is one) and use it as an argument to --exclude-from.  The --remove-source-files option should turn this into a move instead of a copy.  It would look something like...

  rsync --remove-source-files --exclude-from make-it-so.m3u /path/to/itunes/music /tmp/stuff-i-dont-want 
 
+Andy Seibel If you consolidate to a new folder, I think the leftover files will be left in place, so that's where your leftovers will be. This is probably much easier than any kind of programming. 
 
Combining +Magnús Gunnlaugsson's post and mine should get you home safe, as long as you have the hard drive space to duplicate your schtuff.
 
You would have to actually parse the .xml file to grab the Location Keys. Off the top of my head (working in cocoa) I would probably stick those file paths in an NSArray and the read the music folder doing a deep recursion using [NSFileManager enumerateAtPath] and check the array for each file found. If the array does not contain the path, move the file to  the alternate folder. 
 
I think you need AppleScript for this, and I think Doug's Scripts might have covered this.
 
My suggestion contact kris simons he is on g+. He's a guru with scripting, apple, & itunes. Tell him what you need give him 10 mins & you'll have what you need plus it will clean your car, fold your laundry & remember your anniversary
 
+Dieter Pearcey Your suggestion worked perfectly and simply. Thank you!

Everyone who offered code suggestions: thank you! I've been itching to lean a scripting language, and it looks like Python is pretty awesome. I'll be referring to this post a lot in the coming months as I learn as much as I can about programming.
 
I would take the following approach:

First:

Translate the xml file into a plain text file outputting each line as the full path for a song still in your library (using basic javascript and jQuery) http://think2loud.com/224-reading-xml-with-jquery/

Then:

Using sh scripting read the txt file line by line, moving the file to some new directory (like iTunesTMP). 

After that is done, move the remaining files to another temp folder

Then move your library back to its original location
 
If you have it all backed up anyway, have you considered using iTunes Match and then deleting them all? It will stream your songs when you play each one. I have to do that so that I can have all my music on my Macbook Pro. My music library would be 102.65 GB otherwise.
 
Unfortunately, I don't know the format of the iTunes XML file, nor the directory structure of /iTunes/Music, but if you have a way to extract file names with paths, say into /tmp/libraryfiles, you can get the file paths on your disc using "cd /iTunes/Music; find -type f | sort >/tmp/musicfiles".  Then, you can use "comm -13 /tmp/libraryfiles /tmp/musicfiles" to see what lines are only in the second file.  There's probably a more elegant way to move the resultant directory structure to /tmp, but I would probably hack it by adding to the end of the "comm" command line something like
| while read i; do dir=/tmp/"$(basename "$i")"; mkdir -p "$dir"; mv -i "$i" "$dir"; done
(If you aren't using bash, replace the $( and the ) above with back-ticks `.)
 
I did do something like this about 8 years ago. At that time in Perl on Windows (talking to iTunes through the COM interface). It did a whole lot more than that, too, like eliminating duplicates and synchronizing metadata (ratings! Why itunes doesn't believe in 'truth in the file', I'll never know - braindead!). It also detected files where iTunes had peed all over the metadata and refuse to play the file any more (since iTunes 4?5? it's been better about that...) and fixed that (by removing the file from iTunes, cleaning up the metadata, and re-adding it - even takes care of playlists properly.

I've been intending to redo it in Python (where the MP3 metadata libraries are more capable and up to date - I always had to edit the couple of Perl MP3 IDv3 modules to get them to work right with UTF-8 and iTuned provided metadata - IDv3 is about the lamest metadata format I've seen). Copious free time and all that.

For real scripting, I'd never use AppleScript. It will just take up time and have weird edge cases that will cause you to rip your hair out. But on the Mac, you'd probably need small AppleScript stub scripts as helper functions just to deal with iTunes. I'd use a good scripting language - probably Python at this point - as the major piece. To do the job right will take a scripting language with solid data structures. Perl worked, Python would as well. Shell just isn't there.

It also depends on if your looking for a lasting solution or suspect it's a one-time only thing. Me, I've gotten to the point where I know I have to re-rip everything in FLAC (collection originally was ripped 12 years ago) and use MediaMonkey to reflect that into a playground for iTunes to mess up while having a backing script that can pull critical metadata forward into the FLAC tree carefully. I'll still do it on Windows for the OLE access, unless I can find a Python moule to directly interpret the iTunes database.

If you get the sense I don't trust iTunes and metadata, well...
 
If you tell iTunes to change the folder that it keeps its music in, will it copy the music that is still in the iTunes library to that folder, leaving the "deleted" files behind?  I manually manage all of my music now, so I no longer have iTunes installed, but it seems like it would possibly work.
 
xpath is pretty useful for inspecting XML. You can play with it on the command line with "xmllint -shell foo.xml" and then use "ls" and "cd" to navigate around, and you can pass in "xpath" commands like "xpath //tag/text()" (to get the text within tags named "tag").

It sounds like what you want could be done with something like this:

php r '$d = new DOMDocument(); $d>load("Music/iTunes/iTunes Music Library.xml"); $x = new DOMXpath($d); $tracks = $x->query("//key[text()=\"Location\"]/following-sibling::string/text()"); foreach($tracks as $track) { $decoded = urldecode($track->textContent); $decoded = str_replace("file://localhost/","",$decoded); print "$decoded\n"; }'

(That should be php dash r and $d arrow load, $x arrow query, $track arrow textContent. Thanks G+..)

That'll print out a list of all the tracks in your library. I think it should deal with any UTF8 nonsense that may be embedded and it doesn't require you to parse the xml by hand. You'd probably want to do more than just print the file, up to you.
 
Under Windows I have used an app called Clonemaster to track down duplicates, but I'm not sure if there is a Mac version.
 
I guess I would use XSLT to turn the XML into a flat list of file paths then use a script to loop through the actual music files and grep for them in the flat list (then copy any orphans to the special directory you wanted)

There might be other ways to get that XML transformed though, such as importing the XML into Excel and manipulating it from there to get your list if valid files. 
 
First I'd get a magic gourd and a chicken (because anything involving Apple is going to take blood magic)...
 
Hi will, why you dont just re import the library to itself (dragging the whole folder over iTunes) and just delete again de songs.
If you dont want to re pick one by one (to be deleted) you can mark the existings with a metadata field, (than the others will not have)....
Is much easier and effective than scripting...
 
Another option is to do all this within iTunes itself.
Create a playlist, put your entire library in it, add the entire iTunes folder to your library, create a dynamic playlist to list all files not in the other playlist, and then you have a playlist from which to view the files you had removed from your library, along with all their meta data, and delete from both the folder and your library (or open the folder where a file is so you can move it) directly in iTunes.
 
if you don't care about speed/performance that should be enough.. : 

while read line; do
   grep "$line" Library.xml ;
   if [ $? = '1' ] ; then
        rm -rf "$line" ;
    fi ;
done < <(find /iTunes/Music)
 
* Deleted the iPhone/iTune jokes that came to mind inside my head* ;).
 
buy an android smartphone ;) greez from switzerland :D
 
I use a great program called Deltawalker for mac. It compares two files or folders or drives and finds differences and lets you perform actions based on what it finds. It would be perfect for that. I think there is a trial version, I remember trying it first I think before I splurged the $20.
 
+Wil Wheaton There is a much easier way, no script needed... Open iTunes from the file menu add files and folders, pick your /iTunes/Music give it some time to add all the music recursively in that folder (you will not get duplicates because it will not add what you already have in your iTunes Library DB. When it's done create a smart playlist with the date added = the date you do this. Now you'll see all the songs that were orphaned in you /iTunes/Music folder. The trick now is you can't delete from a playlist like you can from the library. The quick fix is change the genre on the songs you really want to delete to "delete me" then go to the main library in iTunes (Music section) filter or sort by genre and delete the "Delete Me" genre files and makes sure to send them to the trash this time. The benefit to this method is you may find sing songs that you didn't know we're missing. 
 
Your first mistake was using iTunes..:P
 
Add them back to iTunes and they'll be the most recently imported songs and then you can delete easily, but send to trash this time. 
 
Honestly, I would do it in python. However I tend to re-invent the wheel. :P
 
i would prefer to do it in matlab, but then i prefer to do everything in matlab..  
 
I would do this in python and leverage its XML parsing libraries... in fact I'm sure someone has already created a module for parsing an iTunes library, so I probably wouldn't even need to parse the XML myself.

Using the os library in python, I'd get a list of files on the filesystem and check each one to see if it's in the iTunes library. If it's not, then I move the file to another location.

You could hack something up that provided enough functionality to do what you needed with a shell script, but the method I've described would both increase confidence that my program was doing what I wanted it to and I would have building blocks for doing other kinds of cool things. :)
 
At 130 comments, I'm betting this problem has been solved many times over.  :)

Now, onto the discovery of which I might have offered...
 
in the \iTunes\Music directory, do the following:
for %a in (*) do if NOT exist \where\ever\%a move %a \tmp
 
Check out this Python script! It's set up for windows, but it would not be hard (for a Person Who Does Programming For Real) to get it working on apple. But this script in fact finds all the tracks on the disc but not in the library.

http://blog.avirtualhome.com/managing-the-itunes-library/

The difficulty is that the iTunes library list is in XML, and shell scripts generally don't parse XML easily, hence the use of Python.

And sure enough, after just these edits, it seems to work for me:

| theITunesDirectory = '/Users/leeduncan/Music/iTunes'
| theLibraryFile = os.path.join(theITunesDirectory,
|                                              'iTunes Music Library.xml')
| theMusicPath = '/Users/leeduncan/Music/iTunes/iTunes Music'
 
I feel for you - Have a similar problem only with graphical as well as text files. Does anyone have an idea for an advanced version of the above mentioned sorting type job for Linux that can do bit by bit comparison of multiple directories - i.e. scan entire drives (multiple mounted volumes) I need to scan a mess of backups ranging from different times and files that may/may not have been edited etc.  differing sizes / content dates etc, needs to be able to create a new folder with files sorted according to for instance names / sizes / content (bitwise) possibly with renaming so as to not overwriting, it would not hurt with a GUI either :)
 
Oh and sorry to hijack the thread but it seems that WIL's problem is fixed and I figured I'd lean on his braintrust since you're all at it already - Have a nice day all!!!
 
iTunes = horrible.
Can't stand the proprietary bullshit that goes with Apple products and their Apps. That's why I use Android products. The above suggestions sound solid, just be leery running any scripts that you don't understand. Good luck WW.
 
Wil, I hope you've backed up your library onto CD/DVDs, because external hard drives are very cheaply made, and aren't reliable. Especially if they're made by Western Digital (WD).
 
I use smart playlists within iTunes to weed through my music often. 
 
Did Will realize what he was opening up here by asking this type of question to his followers?  Too funny!  I was overwhelmed with the first three comments!
 
find, to list all files. grep, to copy the name into a text file if it does not exist in the XML, review manually, when happy pipe to rm, done
 
Not sure what platform you're running, but I know that I would simply use tree. It makes a nice map of your directory structure. Are you wanting to see file names as well to compare which files are in the Library and which files are "checked out"?
 
I would have asked Brent Spiner. *shrug*
 
I agree... You want control of your data, don't use closed systems like anything Apple puts out. It is to restricted, and thats how Steve Jobs always wanted it. He was after all, an technological Tyrant..
 
@David Hooper:What are you talking about? It's just an XML file, not an encrypted binary vault of intractable doom and despair. If you check the option "Keep my music organized", it stores it all in a "/iTunes directory/Artist Name/Album Name/Song Title.xxx" directory structure anyway.
 
Yeah, bash would be incredibly easy. A find command with some simple if logic should do. Although rsync might be simpler.
 
Two things that might help:

1) If the songs were bought through iTunes and not ripped of CD, then you can just re-download the songs again off the store purchased section.  I'm lazy, I tend to let Apple do the work for me.

2) Apple's Spotlight may be able to save you scripting effort by just doing a search and drag.  Spotlight is one of the most powerful searching widgets I've used.  What I write scripts for in Linux, I search and drag for in OSX. You don't have to worry about the already in library issue - just let overwrite or not as part of copy.

3) I let Carbonite (http://www.carbonite.com/en/) take care of the rsyncing for me.  Worth every penny.
Add a comment...