An Applescript that batch-copies the Song tag to the Movement tag

applescriptitunesmusic

I have a rather large iTunes library (~300GB) that is mainly classical music. I really like the Work and Movement format, but sadly it is not practical to manually update my metadata to the Work and Movement format. Almost all of the extisting song tags are in the following format:

Telemann - Concerto in E minor: I. Andante
II. Allegro
III. Largo
IV. Allegro
etc.

A script that could automate updating the tagging system would look like the following.

  1. On all selected songs, copy the Song tag to the Movement tag
  2. Delete the roman numeral, period and space from the front of the Movement tag. Or, on the format where the entire work name in included in the Song tag, delete that.

Any help or pointers for actually implementing this script would be very helpful. I have looked at and used Doug's Work and Movement scripts, but they don't cover the matching process that would be needed to delete the roman numerals from the start.

EDIT

It has become apparent that many of the tags are not in the above format, but in a format like below:

Serenade for strings in C major, Op. 48 - I. Allegro
Serenade for strings in C major, Op. 48 - II. Adagio
Serenade for strings in C major, Op. 48 - III. Allegro moderato
etc.

OR in the same format as above except using arabic numerals in the place of the roman numerals.

The script should result in the "Movement" tags having the following outputs:

Allegro
Adagio
Allegro moderato

The idea is I would get the first part of this ("Serenade for strings in C major, Op. 48") and copy it to the "work" tag, which I have already implemented, then get the remaining text, remove the movement numbers, and assign it to the Movement tag. Any help on implementing a system that would do this would be appreciated.

Here is the script in its current form. It is based on Doug's Name to Work script.

tell application "iTunes"
    set sel to selection of front browser window
    if sel is {} then
        try
            display dialog "Nothing is selected…" buttons {"Quit"} with icon 0
        end try
        return
    end if

    set c to (count of sel)
    set songName to (get name of item 1 of sel)


    set userOptions to display dialog "Edit for Work name and then click OK." default answer songName --prompt for work name

    repeat with i from 1 to c --set the movement numbers
        set thisTrack to item i of sel
        try
            set work of thisTrack to text returned of userOptions
            set movement number of thisTrack to i
            set movement count of thisTrack to c
            set movement of thisTrack to my delRomNum(name of thisTrack) -- copy movement text from song name and delete roman numerals
        end try
    end repeat


end tell

on delRomNum(t) -- the perl command search and delete any roman numeral (must be a word followed by the period and a space character)
    do shell script "/usr/bin/perl -pe 's/\\b[IVXLCDM]+\\b. //g' <<< " & quoted form of t
end delRomNum

Best Answer

To delete the roman numerals, you can use the delRomNum() handler from this script:

--- this text as an example.
set movementText to "Telemann - Concerto in E minor: I. Andante
II. Allegro
III. Largo
IV. Allegro
etc."

set movementText to my delRomNum(movementText) -- delete roman numerals


on delRomNum(t) -- the perl command search and delete any roman numeral (must be a word followed by the period and a space character)
    do shell script "/usr/bin/perl -pe 's/\\b[IVXLCDM]+\\b. //g' <<< " & quoted form of t
end delRomNum

The result of the script is

"Telemann - Concerto in E minor: Andante
Allegro
Largo
Allegro
etc."

Update:

If I understood correctly :

From each line in a string, the command must delete the characters from the beginning of the line through the first occurrence of (a roman numeral or an arabic numeral) followed by the period and a space character, so use this handler:

-- call it, like this --> set movement of thisTrack to my delRomNum(name of thisTrack)
on delRomNum(t)
    (***  from  the contents of the 't' variable (the end of lines must be an Unix Line Endings), so the 'tr' command change the carriage returns (Mac Line Endings) to linefeed (Unix Line Endings)
    the 'perl' command delete the first character in each line through the first occurrence of a word  which contains (a roman numeral or a number) followed by the period and a space character ***)
    do shell script "tr '\\r' '\\n' <<< " & (quoted form of t) & " | /usr/bin/perl -pe 's/^.*?\\b[IVXLCDM0-9]+\\b. //g'"
end delRomNum

Example: the script pass this string to the handler as parameter

Serenade for strings in C major, Op. 48 - I. Allegro
Serenade for strings in C major, Op. 48 - II. Adagio
Serenade for strings in C major, Op. 48 - III. Allegro moderato
Serenade for strings in C major, Op. 48 - 4. Allegro  Molto Appassionato
Serenade for strings in C major, Op. 48 - 5. Adagio - Allegro Molto
Serenade for strings in C major, Op. 48 - 6. Allegro moderato
VII. Adagio - Allegro Non Troppo
8. Allegro Ma Non Tanto
9. Largo
Adagio
etc.

The handler returns:

Allegro
Adagio
Allegro moderato
Allegro  Molto Appassionato
Adagio - Allegro Molto
Allegro moderato
Adagio - Allegro Non Troppo
Allegro Ma Non Tanto
Largo
Adagio
etc.