I have two plist files given by two customers and each times I have to update it manually.
First one I can extract the string I need.
defaults read /Applications/TestAPP/info.plist TestValue
TESTAPP-TESTAPP-TESTAPP
Second one I need to append the previous result at the end of an array inside the second file.
defaults read /Applications/SecondTestAPP/info.plist TestValue2
<key>TEST</key>
<array>
<string>FIRSTONE</string>
<string>SECONDONE</string>
<string>THIRDONE</string>
</array>
</dict>
And I need to add TESTAPP-TESTAPP-TESTAPP
after <string>THIRDONE</string>
Any ideas ?
I already tried: defaults write /Applications/SecondTestAPP/info.plist '<dict><key>TestValue</key><array><string>TESTAPP-TESTAPP-TESTAPP</string></array></dict>'
But it's not working.
Use plutil
Let's start with a plist:
> defaults write org.my.test '{aDict = {anArray = ();};}'
Use plist -p
to print the plist to stdout.
plutil -p ~/Library/Preferences/org.my.test.plist
{
"aDict" => {
"anArray" => [
]
}
}
Use plist -insert
to add something to the array
> plutil -insert aDict.anArray.0 -string a ~/Library/Preferences/org.my.test.plist
> plutil -p ~/Library/Preferences/org.my.test.plist
{
"aDict" => {
"anArray" => [
0 => "a"
]
}
}
Your life will be better if you can insert the new item at the head of the list with index 0.
> plutil -insert aDict.anArray.0 -string before_a ~/Library/Preferences/org.my.test.plist
> plutil -p ~/Library/Preferences/org.my.test.plist
{
"aDict" => {
"anArray" => [
0 => "before_a"
1 => "a"
]
}
}
But if you must put it at the end, then you need to figure out the length of the array. We will do this by first getting the array by itself.
> plutil -extract aDict.anArray json -o - ~/Library/Preferences/org.my.test.plist
["before_a","a"]
To get the number of elements, you can count the number of ',' and then add 1 - but this will have errors if the strings have commas in them.
> echo "$(plutil -extract aDict.anArray json -o - ~/Library/Preferences/org.my.test.plist | grep -F -o ',' | wc -l) + 1" | bc
2
Or you can install jq, a command line tool for reading and manipulating json.
> brew install jq
> plutil -extract aDict.anArray json -o - ~/Library/Preferences/org.my.test.plist | jq '. | length'
2
Then you can use that value to append your value to the end of the array.
> plutil -insert aDict.anArray.$(plutil -extract aDict.anArray json -o - ~/Library/Preferences/org.my.test.plist | jq '. | length') -string b ~/Library/Preferences/org.my.test.plist
> plutil -p ~/Library/Preferences/org.my.test.plist
{
"aDict" => {
"anArray" => [
0 => "before_a"
1 => "a"
2 => "b"
]
}
}
You'll also want to use plutil
to get the value from the other plist
> plutil -extract KEYPATH json -o - OTHER_PLIST
YOUR_VALUE
> plutil -insert aDict.anArray.$(plutil -extract aDict.anArray json -o - ~/Library/Preferences/org.my.test.plist | jq '. | length') -string $(plutil -extract KEYPATH json -o - OTHER_PLIST) ~/Library/Preferences/org.my.test.plist
> plutil -p ~/Library/Preferences/org.my.test.plist
{
"aDict" => {
"anArray" => [
0 => "before_a"
1 => "a"
2 => "b"
3 => "YOUR_VALUE"
]
}
}
It's a bit long, but a one-liner nonetheless.