【问题标题】:extract strings out of plist with bash script, maybe sed?用bash脚本从plist中提取字符串,也许是sed?
【发布时间】:2010-08-13 15:43:16
【问题描述】:

所以这是我的问题。 如何使用 bash 脚本将这些字符串提取到 3 个变量中?

所以就这样吧:

<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 一起使用?

谢谢 德拉库利克斯

【问题讨论】:

    标签: bash sed plist


    【解决方案1】:

    您可以为此使用/usr/libexec/PlistBuddy,它似乎至少从 10.5 (man page) 起就已包含在 OS X 中。示例:

    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 的工具,我认为它对于提取值是可靠的。请注意,键是区分大小写的。

    【讨论】:

    • 我可能会将eval 替换为declare -x $var="$val"
    【解决方案2】:

    假设 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
    

    【讨论】:

      【解决方案3】:

      您可以使用 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/
      

      【讨论】:

        猜你喜欢
        • 2022-07-21
        • 2020-12-04
        • 2012-09-17
        • 1970-01-01
        • 2011-02-07
        • 2015-06-19
        • 1970-01-01
        • 1970-01-01
        • 2017-01-31
        相关资源
        最近更新 更多