Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extract strings out of plist with bash script, maybe sed?

Tags:

bash

sed

plist

So here is my problem. How can I extract those strings into 3 variables with a bash script?

So out of this:

<key>GameDir</key> <string>C:/Program Files/</string> <key>GameEXE</key> <string>C:/Program Files/any.exe</string> <key>GameFlags</key> <string>-anyflag</string>

I want:

GameDir=C:/Program Files/
GameEXE=C:/Program Files/any.exe
GameFlags=-anyflag

Example Script:

echo GameDir
echo GameEXE
echo GameFlags

Example Output:

C:/Program Files/
C:/Program Files/any.exe
-anyflag

The order of the keys is not changing, only the strings itself. I am using OS X, so it needs to be a command that works out-of-the-box on OS X. Maybe this could work with sed?

Thanks Drakulix

like image 990
Drakulix Avatar asked Dec 23 '22 00:12

Drakulix


2 Answers

You could use /usr/libexec/PlistBuddy for this, which seems to be included in OS X since at least 10.5 (man page). Example:

file="$HOME/yourfile"
/usr/libexec/PlistBuddy -c "Print" "$file"

And you could assign the vars you're interested in like this:

for var in GameDir GameEXE GameFlags ; do
    val=$( /usr/libexec/PlistBuddy -c "Print $var" "$file" )
    eval "export $var='$val'"
    echo "$var = $val"
done

It seems more readable than bash/sed/awk regexes, and since it is a plist-specific tool, I presume it is reliable for extracting values. Just be aware that the keys are case-sensitive.

like image 51
mivk Avatar answered Jan 05 '23 19:01

mivk


Assuming Bash version >= 3.2

string='<key>GameDir</key> <string>C:/Program Files/</string> <key>GameEXE</key> <string>C:/Program Files/any.exe</string> <key>GameFlags</key> <string>-anyflag</string>'

or

string=$(<file)

and

pattern='<key>([^<]*)</key>[[:blank:]]*<string>([^<]*)</string>[[:blank:]]*'
pattern=$pattern$pattern$pattern
[[ $string =~ $pattern ]]    # extract the matches into ${BASH_REMATCH[@]}
for ((i=1; i<${#BASH_REMATCH[@]}; i+=2))
do
    declare ${BASH_REMATCH[i]}="${BASH_REMATCH[i+1]}"    # make the assignments
done
echo $GameDir    # these were missing dollar signs in your question
echo $GameEXE
echo $GameFlags
like image 28
Dennis Williamson Avatar answered Jan 05 '23 17:01

Dennis Williamson