1

I have some plist files on Mac OS X that I would like to shrink. They have a lot of <dict> with <key> and values. One of these keys is a thumbnail which has a <data> value with base64 encoded binary (I think). I would like to remove this key and value.

I was thinking this could maybe be done by sed, but I don't really know how to use it and it seems like sed only works on a line-by-line basis?

Either way I was hoping someone could help me out. In the file I would like to delete everything that matches the following pattern or something close to that:

<key>Thumbnail<\/key>[^<]*<\/data>

In the file it looks like this:

            // Other keys and values

            <key>Thumbnail</key>
            <data>
            TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB

            ...

            dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
            </data>

            // Other keys and values

Anyone know how I could do this? Also, if there are any better tools that I can use in the terminal to do this, I would like to know about that as well :)

4 Answers 4

4

There are two utilities available on the command line specifically devoted to working with preference list files: defaults (in /usr/bin) and PlistBuddy in (/usr/libexec).

Still using sed:

sed does allow a multiple line delete using the D instead of the d flag.

eg. sed -e '/<key>Thumbnail<\/key>/, /<\/data>/D' < /PATH/TO/FILE.txt removes all instances of the key Thumbnail and it's associated data.

Using defaults:

defaults delete /PATH/TO/PLIST "Thumbnail". Do not include the .plist extension as part of the path. Also, this will only work on root level items in a .plist, so if the Thumbnail key is inside another array or dict it won't work.

Using PlistBuddy:

/usr/libexec/PlistBuddy -c "Delete :Thumbnail" /PATH/TO/PLIST.plist. If the Thumbnail key is nested, you can append the path before it if you know it. eg. PlistBuddy -c "Delete :User:Thumbnail" if the Thumbnail entry was in a User dictionary.

0

XMLStarlet is an awesome command line tool for manipulating XML. The main problems with it are 1) it's a very complex tool (since it does very complex jobs), and 2) you'd probably have to build it for OS X yourself.

0

use awk, not sed

$ cat file
asdkf
asdklf
            // Other keys and values

            <key>Thumbnail</key>
            <data>
            TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB

            ...

            dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
            </data>

            // Other keys and values

ksdf

$ awk 'BEGIN{RS="</data>"} /<key>/{ gsub("<key>.*</key>|<data>.*","") }1' file
asdkf
asdklf
            // Other keys and values





            // Other keys and values

ksdf

the statement says, use </data> as record separator, then replace tags <key> and <data> with nothing, when <key> is found in the record

0

It might be possible to do this with sed, but it would be difficult. Perl could do this more easily. The guts of the perl script would be:

undef $/; # This allows reading in of all lines in one swoop

$contents = <>; # Read in contents of file (specified on command line)

$contents = s{<key>Thumbnail</key>.*?</data>}{}s;

print $contents;

If you had the above in a perl script called change.plx and you had your data in a file called keyfile, then you could fix up that file by doing:

$ perl change.plx keyfile > /tmp/$$ && cat /tmp/$$ > keyfile && rm /tmp/$$

Of course, make sure you have a backup of any file that you do this to. It's possible to do all this work on multiple files with a single one line perl program on the command line like this:

$ perl -p0777i -e 's{<key>Thumbnail</key>.*?</data>}{}s;' file file file ...

Marnix

2
  • Something was deleted from my regular expressions. I'm new to this site and I'm guessing that any html-like expressions need to be escaped. The regular expression was supposed to be (hopefully it will work in this comment): s{Thumbnail.*?</data>}{}s Marnix Apr 7, 2010 at 17:32
  • 1
    You need to indent your code example with 4 spaces. Think there also is a code button above the editor that you can click while having your code selected.
    – Svish
    Apr 7, 2010 at 20:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .