1

У меня есть некоторые файлы plist на Mac OS X, которые я бы хотел сжать. У них много <dict> с <key> и значениями. Одним из этих ключей является миниатюра, которая имеет значение <data> с двоичным кодом в кодировке base64 (я думаю). Я хотел бы удалить этот ключ и значение.

Я думал, что это может быть сделано с помощью sed, но я не знаю, как его использовать, и кажется, что sed работает только построчно?

В любом случае я надеялся, что кто-нибудь может мне помочь. В файле я хотел бы удалить все, что соответствует следующему шаблону или что-то похожее на это:

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

В файле это выглядит так:

            // Other keys and values

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

            ...

            dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
            </data>

            // Other keys and values

Кто-нибудь знает, как я мог это сделать? Кроме того, если для этого есть какие-то инструменты, которые я могу использовать в терминале, я бы тоже хотел об этом узнать :)

4 ответа4

4

В командной строке доступны две утилиты, специально предназначенные для работы с файлами списка предпочтений: defaults/usr/bin) и PlistBuddy в (/usr/libexec).

Все еще использую sed:

sed допускает удаление нескольких строк, используя D вместо флага d .

например. sed -e '/<key>Thumbnail<\/key>/, /<\/data>/D' < /PATH/TO/FILE.txt удаляет все экземпляры ключа Thumbnail и связанные с ним данные.

Используя defaults:

defaults delete /PATH/TO/PLIST "Thumbnail" . Не включайте расширение .plist как часть пути. Кроме того, это будет работать только с элементами корневого уровня в .plist , поэтому, если ключ Thumbnail находится внутри другого массива или dict, он не будет работать.

Использование PlistBuddy:

/usr/libexec/PlistBuddy -c "Delete :Thumbnail" /PATH/TO/PLIST.plist . Если ключ миниатюры является вложенным, вы можете добавить путь до него, если вы его знаете. например. PlistBuddy -c "Delete :User:Thumbnail" если запись Миниатюра была в пользовательском словаре.

0

используйте awk, а не 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

В заявлении говорится, что используйте </data> качестве разделителя записей, затем замените теги <key> и <data> ничем, когда <key> найден в записи.

0

Это может быть возможно сделать с помощью sed, но это будет сложно. Perl мог бы сделать это проще. Внутренности сценария Perl будут:

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;

Если у вас есть вышеперечисленное в perl-скрипте с именем change.plx, и ваши данные находятся в файле с именем keyfile, то вы можете исправить этот файл, выполнив:

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

Конечно, убедитесь, что у вас есть резервная копия любого файла, с которым вы делаете это. Можно выполнить всю эту работу над несколькими файлами с помощью одной однострочной perl-программы в командной строке следующим образом:

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

Marnix

0

XMLStarlet - это потрясающий инструмент командной строки для управления XML. Основные проблемы с ним:1) это очень сложный инструмент (поскольку он выполняет очень сложные задачи), и 2) вам, вероятно, придется создать его для OS X самостоятельно.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .