Ornithopter
Ornithopter

Reputation: 2088

Parsing dictionary from plist into array in bash

Here is the plist file:

<?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>Applications</key>
    <string>应用程序</string>
    <key>Compositions</key>
    <string>Compositions</string>
</dict>
</plist>

I use PlistBuddy in bash to print this plist. And I got the result like this:

Dict {
    Applications = 应用程序
    Compositions = Compositions
}

How can I parse string above into an array like this in bash?

array[0]="应用程序" array[1]="Compositions"

Upvotes: 2

Views: 3740

Answers (3)

Ornithopter
Ornithopter

Reputation: 2088

This solution works for me (Thanks to BallPython)

#!/bin/bash
RootDir=/System/Library/CoreServices/SystemFolderLocalizations/zh_CN.lproj
FileName=SystemFolderLocalizations.strings
PB=/usr/libexec/PlistBuddy

list=`$PB -c "Print" $RootDir/$FileName`

items=`awk -F" = " '
{
    if ($0 ~ /[{}]/){}
    else{printf $1","}
}' <<< "${list}"`

IFS=',' read -ra array <<< "$items"

for element in "${array[@]}"
do
    echo "$element"
done

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84609

For a pure bash solution, the easiest way to parse the plist file, in the absence of a plist parser (and absent using sed or awk), is to read the plist file and add the entries using parameter expansion/substring extraction to get the actual values from the script lines. An example would be:

#!/bin/bash

test -n "$1" -a -r "$1" || {
    printf "\nerror: invalid input.  Usage:  %s plist_file\n\n" "${0//*\//}"
    exit 1
}

declare -a plarray

while read -r line || test -n "$line" ; do
    test "${line:0:8}" = "<string>" || continue
    tmp="${line//<string>/}"
    tmp="${tmp//<\/string>/}"
    plarray+=( "$tmp" )
done <"$1"

for ((i=0; i<${#plarray[@]}; i++)); do
    printf " array[%d]=\"%s\"\n" "$i" "${plarray[i]}"
done

exit 0

output:

$ bash readplist.sh dat/plist.txt
 array[0]="应用程序"
 array[1]="Compositions"

Note: parsing text with bash can be tricky, if there is a plist/xml parser, it should be used as a first choice to extract the values.

Upvotes: 2

midori
midori

Reputation: 4837

I'm not sure if it's what you really wanted but in your case it will create an array for you of what you wanted:

dict=($(awk '/=/{ print $3 }' <<< "$(your plist result here)"))

Test:

echo "${dict[@]}"

Output:

应用程序 Compositions

Upvotes: 4

Related Questions