извлекать строки из plist скриптом bash, может быть, sed? - PullRequest
3 голосов
/ 13 августа 2010

Итак, вот моя проблема.Как мне извлечь эти строки в 3 переменные с помощью bash-скрипта?

Итак, из этого:

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

Я хочу:

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

Пример сценария:

echo GameDir
echo GameEXE
echo GameFlags

Пример вывода:

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

Порядок клавиш не меняется, только сами строки.Я использую OS X, поэтому это должна быть команда, которая работает из коробки на OS X. Может быть, это может работать с sed?

Спасибо Drakulix

Ответы [ 3 ]

7 голосов
/ 12 июля 2012

Вы можете использовать /usr/libexec/PlistBuddy для этого, который, кажется, включен в OS X, начиная с 10.5 ( man page ). Пример:

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

И вы можете назначить интересующие вас переменные следующим образом:

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, и, поскольку это инструмент, относящийся к plist, я предполагаю, что он надежен для извлечения значений. Просто помните, что ключи чувствительны к регистру.

3 голосов
/ 13 августа 2010

Предполагается, что версия Bash> = 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
0 голосов
/ 14 августа 2010

вы можете использовать awk, это работает для многострочных и множественных ключей, строковых значений.

$ 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

Используйте eval для создания переменных

$ eval $(awk -vRS="</string>" '/<key>/{gsub(/<key>|<string>|\n| +/,"") ; sub("</key>","=") ;print}' file )
$ echo $GameDir
C:/ProgramFiles/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...