I noticed that I have many (hundreds) duplicate field names and values in my OS X 10.8.5 Contacts. "Field names and values" are probably not the right words, but what I mean is, that I have many contact cards that seem to have identical fields like this:

enter image description here

The problem is not confined to social profiles. Also emails, addresses, phones, (and maybe more) suffer from duplication.

I got introduced to AppleScript yesterday, and although I do get it a little (can run them, can play around a bit with existing scripts, know about save :)), this is still beyond my capabilities:

I would be really helped by such an AppleScript that removes duplicate fields per card if they have the same type(?) and the same label(?) and the same value(?). (But keeping one instance.)

I can imagine that addresses (with street, postal code, etc), might be asking too much. But, non-composite "fields" would already clean up my address book significantly.

Apologies for surely not getting the technical terms right.

有帮助吗?

解决方案

This is an example. Tested on only two contacts which I manufactured duplicate fields. And placed them in a group for testing

This should give you an idea of one way to construct the code.

The example is as is, as I did not want to spend too much time on it. But worked in my tests.

The example will remove duplicate Social profiles and phone numbers fields in a contact.

In the Social profiles the delete action is repeated. This is because the first delete forces the contacts.app to replace the entry with an URL for the social media site.

The construction for the other fields should be relatively easy from here.

Each set of fields i.e phones, social profile, email should have it's own run handler to make the code more manageable. Like I have done here.

You should also note that doing any of this on a large set of contacts could take a very long time.

YOU SHOULD ALSO BACK UP THE ADDRESS BOOK CONTACTS BEFORE PLAYING WITH ANY OF THIS. AND USE AT YOUR OWN RISK

set targetGroup to "BD"


tell application "Contacts" to set thePeople to people of group targetGroup -- TEST GROUP OF PEOPLE
---- tell application "Contacts" to set thePeople to people  -- ALL PEOPLE 

(* Run the Handler for  Social profiles*)
my deleteSocialEntries(thePeople)

(* Run the Handler for  phones *)
my deleteSocialPHONE(thePeople)

(* Handlers*)
on deleteSocialPHONE(thePeople)

    tell application "Contacts"




        (* iterate over the people - get each person in the contacts*)
        repeat with i from 1 to number of items in thePeople
            set this_person to item i of thePeople

            (*get all the phones of the person*)
            set theFields to (properties of phones of this_person)


            set keepers to {}
            (* iterate over the phones and get a phone's value*)
            repeat with i from 1 to number of items in theFields
                set this_item to item i of theFields
                set thisValue to value of this_item

                if thisValue is not in keepers then
                    (* Not in the list of keepers so add it*)
                    copy thisValue to end of keepers

                else
                    (* Was already  in the list of keepers try and delete it*)
                    try
                        set thisID to id of this_item
                        set thisD to (every phone of this_person whose id is thisID)

                        delete (item 1 of thisD)

                        save
                    end try
                end if


            end repeat

        end repeat
    end tell

end deleteSocialPHONE


on deleteSocialEntries(thePeople)
    set social to {"Twitter", "Linkedin", "Facebook"}
    tell application "Contacts"




        (* iterate over the people - get each person in the contacts*)
        repeat with i from 1 to number of items in thePeople
            set this_person to item i of thePeople

            (* iterate over the social media types for this person *)
            repeat with i from 1 to number of items in social
                set this_soc to item i of social
                (*get all the *type* of social profiles of the person*)
                set theFields to (properties of every social profile of this_person whose service name is this_soc)

                set keepers to {}
                (* iterate over the ocial profile  and get a user name value*)
                repeat with i from 1 to number of items in theFields
                    set this_item to item i of theFields
                    set thisValue to user name of this_item

                    if thisValue is not in keepers then
                        copy thisValue to end of keepers
                    else
                        (* Was already  in the list of keepers try and delete it*)
                        set thisID to id of this_item
                        set thisD to (every social profile of this_person whose id is thisID)

                        delete (url of item 1 of thisD)
                        delete (user name of item 1 of thisD)

                        delete (url of item 1 of thisD)
                        delete (user name of item 1 of thisD)
                        save

                    end if
                end repeat

            end repeat

        end repeat
    end tell

end deleteSocialEntries
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top