How do I replace a value in an plist array using plutil? I'm trying to change a value in an array using plutil, but I get the error


  Failed to insert value new value 2 at key path PARENT.0.KEY_IN_ARRAY with error -[__NSCFConstantString characterAtIndex:]: Range or index out of bounds


Here's a sample plist to illustrate the problem:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
  &lt;key&gt;SIMPLE&lt;/key&gt;
  &lt;string&gt;value1&lt;/string&gt;
  &lt;key&gt;PARENT&lt;/key&gt;
  &lt;array&gt;
    &lt;dict&gt;
      &lt;key&gt;KEY_IN_ARRAY&lt;/key&gt;
      &lt;string&gt;value2&lt;/string&gt;
    &lt;/dict&gt;
    &lt;dict&gt;
      &lt;key&gt;KEY_IN_ARRAY&lt;/key&gt;
      &lt;string&gt;value3&lt;/string&gt;
    &lt;/dict&gt;
  &lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;


Modifying the SIMPLE value is easy:

$ plutil -extract SIMPLE xml1 -o - sample.plist 
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;string&gt;value1&lt;/string&gt;
&lt;/plist&gt;

$ plutil -replace SIMPLE -string "new value 1" sample.plist 

$ plutil -extract SIMPLE xml1 -o - sample.plist 
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;string&gt;new value 1&lt;/string&gt;
&lt;/plist&gt;


Getting the array value works fine:

$ plutil -extract PARENT.0.KEY_IN_ARRAY xml1 -o - sample.plist 
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;string&gt;value2&lt;/string&gt;
&lt;/plist&gt;


but I get the error when I try to modify this value:

$ plutil -replace PARENT.0.KEY_IN_ARRAY -string "new value 2" sample.plist 
sample.plist: Could not modify plist, error: Failed to insert value new 
value 2 at key path PARENT.0.KEY_IN_ARRAY with error -[__NSCFConstantString 
characterAtIndex:]: Range or index out of bounds
I think PlistBuddy is the recommended tool here:

/usr/libexec/PlistBuddy -c "Set :PARENT:0:KEY_IN_ARRAY valueX" sample.plist 


The command modifies the value of KEY_IN_ARRAY in the first dict of PARENT. The one in the second dict would be changed with:

/usr/libexec/PlistBuddy -c "Set :PARENT:1:KEY_IN_ARRAY valueY" sample.plist 


The -c switch executes the command directly. The file mustn't be a binary plist!