Как добавить значения во вложенные массивы или dicts с помощью команды "запись по умолчанию"?

Рассмотрим список предпочтений с помощью dict, который содержит массив:

Давайте создадим это:

defaults write org.my.test '{aDict = {anArray = ();};}'

Тогда прочитайте это назад, чтобы увидеть структуру лучше:

$defaults read org.my.test
{
    aDict = {
        anArray = (
        );
    };
}

Теперь, как мне добавить значение anArray с использованием defaults write команда?

Я знаю, что есть -array-add тип для добавления значений в массив, но как указать путь к ключу элемента массива?

Я пробовал это, но это не работает:

defaults write org.my.test aDict.anArray -array-add "a value"

На самом деле мне нужно добавить нестроковый тип, поэтому мне также нужно иметь возможность указать тип, например -bool YES,

(Примечание: я не могу использовать ни PlistBuddy, ни plutil, так как это должно влиять на живые настройки)

3 ответа

Использование plutil и твоя жизнь станет лучше Значения по умолчанию не поддерживают ключевые пути.

> defaults write org.my.test '{aDict = {anArray = ();};}'

> defaults read org.my.test
{
    aDict =     {
        anArray =         (
        );
    };
}

> plutil -insert aDict.anArray.0 -bool YES ~/Library/Preferences/org.my.test.plist

> defaults read org.my.test
{
    aDict =     {
        anArray =         (
            1
        );
    };
}

я использовал defaults read просто чтобы доказать, что ожидаемые входные данные одинаковы, но вы, вероятно, будете использовать plutil -p ~/Library/Preferences/org.my.test.plist вместо этого, чтобы прочитать файл, если вы начнете использовать plutil Больше.

Это расширяет идею Томаса Темпельмана и работу Лияна Чанга и касается cfprefsd с использованиемdefaultsкоманда, чтобы переписать plist, который, похоже, работает сcfprefsd: 1 2

      defaults write org.my.test '{aDict = {anArray = ();};}'
defaults export org.my.test /tmp/foo.plist
plutil -insert aDict.anArray.0 -bool YES /tmp/foo.plist
defaults import org.my.test /tmp/foo.plist

Или вы можете сделать все это в одной строке:

      defaults write org.my.test "$(defaults export org.my.test - | plutil -insert aDict.anArray.0 -bool YES - -o -)"

Здесь это расширено и легче следовать:

      > defaults write org.my.test '{aDict = {anArray = ();};}'

> defaults export org.my.test -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>aDict</key>
    <dict>
        <key>anArray</key>
        <array/>
    </dict>
</dict>
</plist>

> defaults export org.my.test /tmp/foo.plist

> plutil -insert aDict.anArray.0 -bool YES /tmp/foo.plist

> defaults import org.my.test /tmp/foo.plist

> defaults export org.my.test -                                   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>aDict</key>
    <dict>
        <key>anArray</key>
        <array>
            <true/>
        </array>
    </dict>
</dict>
</plist>
> 

Также вместо того, чтобы делатьdefaults write org.my.test '{aDict = {anArray = ();};}'что затрудняет определение типов, которые вы можете сделать в виде списка, напримерdefaults write org.my.test '<dict><key>aDict</key><dict><key>anArray</key><array/></dict></dict>что облегчает просмотр типов, но занимает гораздо больше времени.

Возможно, существует способ экспортировать весь набор настроек в XML, затем изменить этот текст, чтобы включить изменения, а затем повторно импортировать XML в настройки.

По сути, вы бы использовалиdefaults exportчтобы создать вывод XML, то что-то вродеsed(см. здесь пример ), затем используйтеdefaults importчтобы вернуть его в настройки.

Я не нашел для этого общего метода, так что это всего лишь заглушка, но если вы это поймете, отредактируйте этот ответ, так как я сделаю его записью «вики-сообщества», чтобы каждый мог ее изменить.

Другие вопросы по тегам