【问题标题】:shell script (macOS): print escaped Unicode character from a plist stringshell 脚本 (macOS):从 plist 字符串中打印转义的 Unicode 字符
【发布时间】:2017-03-17 15:22:14
【问题描述】:

在一个 shell 脚本中,我从应用程序包中的 Info.plist 中读取字符串,在本例中从版权键读取字符串,而 $FILEPATH 是应用程序包的路径,例如/Applications/TextEdit.app

#!/bin/bash  
PLIST=$(/usr/bin/defaults read "$FILEPATH/Contents/Info.plist")
COPYRIGHT=$(echo "$PLIST" | /usr/bin/awk -F" = " '/NSHumanReadableCopyright/{print $2}' RS=';' | /usr/bin/sed 's/^"\(.*\)"$/\1/')
echo "Copyright: $COPYRIGHT"

注意:我不是直接读取密钥,这当然更容易;它被读入变量 PLIST,因此脚本稍后也可以读取其他键,并且不必一遍又一遍地使用 defaults 命令。

现在输出是(例如)Copyright: Copyright \\U00a9 1995-2015, Apple Inc.\\nAll rights reserved.

显然版权符号 \U00a9 被转义了,换行符也是如此,但是我怎样才能解决这个问题,以便 shell 脚本实际打印出字符串,即使用版权符号和换行符?

PS:最后我可能会删除换行符,但作为第一步,我想按预期回显整个内容。

【问题讨论】:

    标签: bash macos unicode plist defaults


    【解决方案1】:

    我会使用plutil 而不是defaults。该:

    plist="/Applications/TextEdit.app/Contents/Info.plist"
    plutil -p - < "$plist"
    

    将打印

    ... some lines deleted...
      "DTSDKName" => "macosx10.12internal"
      "DTXcode" => "0800"
      "NSHumanReadableCopyright" => "Copyright © 1995-2016, Apple Inc.
    All rights reserved."
      "DTSDKBuild" => "16C7"
      "CFBundleDevelopmentRegion" => "English"
    ... other delted lines ...
    

    -p 的意思是 人类可读的格式 - 很难处理。因此,最好将plist 转换为json,例如:

    plutil -convert json -r -o - - < "$plist"
    

    -r 的意思是转换为人类可读的JSON,例如

    {
      "CFBundleName" : "TextEdit",
      "DTSDKName" : "macosx10.12internal",
      "DTXcode" : "0800",
      "NSHumanReadableCopyright" : "Copyright © 1995-2016, Apple Inc.\nAll rights reserved.",
      "DTSDKBuild" : "16C7",
      "CFBundleDevelopmentRegion" : "English",
      "CFBundleVersion" : "329",
    

    现在您可以轻松过滤掉NSHumanReadableCopyright 键,即使使用awk,但最好使用一些真正的 工具。

    Mac 默认安装了perlJSON::PP 模块。所以:

    plist="/Applications/TextEdit.app/Contents/Info.plist"
    plutil -convert json -r -o - - < "$plist" |\
    /usr/bin/perl -0777 -CSDA -MJSON::PP -MEncode -E '$p=decode_json(encode_utf8(<>));say $p->{NSHumanReadableCopyright}'
    

    会输出

    Copyright © 1995-2016, Apple Inc.
    All rights reserved.
    

    编辑: 将整个测试作为评论中的一长行:

    plist="/Applications/TextEdit.app/Contents/Info.plist"; jplist=$(/usr/bin/plutil -convert json -r -o - "$plist"); copyright=$(echo "$jplist" | /usr/bin/perl -0777 -CSDA -MJSON::PP -MEncode -E '$p=decode_json(encode_utf8(<>));say $p->{NSHumanReadableCopyright}'); echo "$copyright"
    

    然后打印OK...

    【讨论】:

    • 我可能建议引用"/Applications/TextEdit.app/Contents/Info.plist"(以防在处理其他应用程序名称时可能有空格,或者如果 $plist 变量没有碰巧是)。
    • 效果很好。谢谢你。然而,不起作用的是将 JSON plutil 输出放入一个变量中,比如 jplist,然后将其回显并将其传递给 perl 命令。 jplist=$(/usr/bin/plutil -convert json -r -o - "$plist") ; copyright=$(echo "$jplist" | /usr/bin/perl -0777 -CSDA -MJSON::PP -MEncode -E '$p=decode_json(encode_utf8(&lt;&gt;));say $p-&gt;{NSHumanReadableCopyright}') ; echo "$copyright" (这没什么大不了的,因为 plutil + perl 本身似乎已经足够快了。)
    • 不,实际上我现在测试了它,使用 plutil + perl 分别为每个键读取大量 plist 键,与单个默认值 read + echo & awk 相比,它非常慢。所以 plutil + perl 组合只适用于可能对标准输出造成问题的特定键。
    • 啊,没有刷新并查看编辑...现在将对其进行测试。谢谢。
    • @JayB - 每一个键是什么意思?你在做别的事情。 JSON 是标准化格式。我回答了关于版权的问题——如果你想做其他事情——问一个新问题。 :)
    猜你喜欢
    • 1970-01-01
    • 2014-08-23
    • 2013-05-23
    • 1970-01-01
    • 2015-09-14
    • 2017-11-28
    相关资源
    最近更新 更多