Extract strings from plist using bash script, maybe sed?

So here is my problem. How can I extract these lines into 3 variables using a bash script?

So from 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 to:

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

Script example:

echo GameDir
echo GameEXE
echo GameFlags

Result:

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

The order of the keys does not change, only the lines themselves. I use OS X, so it should be a command that works out of the box on OS X. Maybe this could work with sed?

Thanks Drakulix

+3
source share
3 answers

You can use one /usr/libexec/PlistBuddyfor this, which seems to be included in OS X with at least 10.5 ( man page ). Example:

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

And you can designate your interests 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

, bash/sed/awk regexes, , plist, , . , .

+7

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>'

string=$(<file)

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
+3

you can use awk, this works for multi-line and multiple keys, string values.

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

$ awk -vRS="</string>" '/<key>/{gsub(/<key>|<string>|\n| +/,"") ; sub("</key>","=") ;print}' file
GameDir=C:/ProgramFiles/
GameEXE=C:/ProgramFiles/any.exe
GameFlags=-anyflag

Use eval to create variables

$ eval $(awk -vRS="</string>" '/<key>/{gsub(/<key>|<string>|\n| +/,"") ; sub("</key>","=") ;print}' file )
$ echo $GameDir
C:/ProgramFiles/
0
source

Source: https://habr.com/ru/post/1759551/


All Articles