IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]macOS: 使用新版plutil命令操作Plist文件更方便

    afatgoat发表于 2017-01-26 15:00:44
    love 0

    • 前言
    • 介绍
      • 测试环境
        • 创建空Plist文件
      • 在线帮助
      • 验证Plist文件格式
      • 显示文件内容
      • 转换格式
      • 创建简单键值
      • 删除一个键
      • 替换一个键值
      • 提取一个键值
      • 复杂键值操作
        • 数组
        • 字典
        • 复杂类型的标识
        • 举例
      • 数组
        • 创建数组
        • 插入数组项
        • 删除数组项
        • 替换数组项
      • 字典
        • 创建字典
        • 插入字典项目
        • 删除数组项
        • 替换数组项
    • 后序
      • 命令比较
        • 参考

    前言

    自从OS X 10.11和更新版macOS 10.12操作系统发布以来,plutil命令的功能也随之有了增强,使我们可以除了使用defaults和PlistBuddy命令之外,又多了一个有力的操作工具。

    最早plutil命令单单用来对Plist文件进行语法验证和格式转换,没有太多的用途。现在它除了部分功能,如显示部分不如defaults和PlistBuddy灵活外,对于Plist的写操作有了突出的改进,比defaults要简单,与PlistBuddy不相上下。

    下面就介绍下它的具体功能。

    介绍


    Plist文件是由一对一对的“键”和“值”组成的,键(Key)是后面值(Value)的名称,值可能是简单的数值或字符串,也可能是复杂的数据,这在后面具体说。

    测试环境

    首先,为了方便,我们现在当前用户目录下面建立一个空目录:~/plutil_temp,然后在Termianl中转到该目录为当前目录,后面的测试我们都在该目录下进行。

    mkdir -p ~/plutil_temp
    cd ~/plutil_temp

    创建空Plist文件

    由于plutil命令还不支持创建一个空的Plist文件,我们可以用下面命令创建一个空的文件:

    echo '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict/></plist>' > example.plist

    注意上面的命令是一行命令,不分行。

    或者使用其他命令创建带有初始值的Plist文件,比如:

    /usr/libexec/plistbuddy -c Set: example1.plist

    虽然它会显示错误信息,但是依然可以成功创建一个空的原始Plist文件。
    也可以尝试使用defaults命令创建一个,这里不再赘述。


    在线帮助

    先来显示一下它的在线帮助:

    plutil -h

    先仔细看一下它的在线帮助

    验证Plist文件格式

    现在让我们来验证一下我们前面建立的空Plist文件格式是否正确:

    plutil -lint example.plist

    如果文件格式没问题,会在stdout中显示OK,同时返回值为0


    显示文件内容

    这个也很简单,使用-p命令:

    plutil -p example.plist

    显示结果:

    {
    }

    请记住它的输出格式,这种格式叫做json,其实plutil只支持json格式输出的。
    不妨试试,用诸如cat命令来显示我们的示例文件,它应该是XML格式的文本文件:

    cat example1.plist

    上面的命令显示的就是标准的XML文本格式的Plist文件。
    请记住两个输出的不同,最好再看一下文件的大小。
    下面我们详细说plist文件格式


    转换格式

    Plist支持三种格式: xml1, json和binary,前两者都是纯文本格式,后一种是二进制格式。也就是说前两种使用文本编辑器方便地编辑,二进制格式就不好手动编辑了。如果需要手动编辑,还是先转化为文本格式,完成后再转化回二进制格式。

    一般来说,对于使用操作系统提供的标准Plist文件操作API,无论是哪种格式都正常可以操作,没有任何差别。

    转换格式使用-convertml命令:

    plutil -convert json example.plist

    转换之后,我们再来看看文件的大小。是不是变化了?!

    一个小启发,能不能用另外一种更简单的方式创建一个新的Plist文件呢?


    创建简单键值

    Plist文件支持下面的简单类型:

    类型 说明
    -bool 布尔型
    -integer 64位整数
    -float 64位浮点数
    -string 字符串
    -date 时间
    -data 数据(是base-64转码字符串)

    创建使用-insert(插入)命令。我们一一举例说明

    plutil -insert Agree -bool "Yes" example.plist
    plutil -insert Passed -bool "True" example.plist
    plutil -insert Count -integer 10 example.plist
    plutil -insert Total -float 9876.54321 example.plist
    plutil -insert LastName -string "Liu" example.plist
    plutil -insert FirstName -string "Tony" example.plist
    plutil -insert Content -data "cGx1dGls5ZG95Luk5omp5bGV5LuL57uNCg==" example.plist

    这些都很简单,但是-date类型有点麻烦,至今为止已知的时间类型它都不支持,根据plutil的在线说明
    “-date: a date in XML property list format,”
    我们只好使用后面才提到的XML格式,这在后面一节统一介绍。至于为什么只能这样,还不知道。


    删除一个键

    删除使用-remove命令,举例说

    plutil -remove Passed example.plist

    替换一个键值

    替换使用-replace命令,举例说

    plutil -replace Total -float 9876.54321 example.plist

    提取一个键值

    plutil没有一个内置命令用于显示某一项的值。其中一种方法,虽然有点笨重,我们可以利用-extract命令来实现。
    比如我们要显示LastName的内容:

    plutil -extract LastName xml1 example.plist -o LastName.plist; plutil -p LastName.plist

    它的过程是,使用-extract来讲需要的项提取到一个新的plist文件中(LastName.plist),然后在显示它的内容。
    其实还可以有很多其他方法,留给读者自己考虑


    复杂键值操作

    好了这是它的精华之处了。
    话说一个Plist文件,之所以可以包含多种的键和值,关键一点就是它的根一定是一个字典类型,在XML中以表示。下面我们说说他的复杂类型。
    复杂键值包括数列和字典。

    数组

    什么是数组?数组是同质数据的集合,可以使用整数作为索引访问每个数据对象。什么是”同质数据“呢,就是说,一个数组中如果任何一个数据是浮点数类型,那么所有的都是浮点数类型。
    数组的数据也可以是后面说的”字典“类型,至于数组中每个字典是否机构相同,Plist中没有强制要求,所以可以不同。

    字典

    什么是字典类型呢?它是一种可以包含子键值对的对象数据。子键值对可以是前面说的任意的简单和复杂类型。

    复杂类型的标识

    在plutil命令中,可以使用下面两种方式表示

    类型 说明
    -xml XML格式
    -json JSON格式

    举例

    记得前面提到的无法使用-date输入一个时间类型的值把,我们这里就使用-xml来实现

    plutil -insert CreateTime -xml "<date>2017-01-26T04:59:49Z</date>" example.plist

    看见了,和之间的就是ISO8601的UTC日期与时刻表示法的字符串格式


    数组

    我们下面通过具体操作来介绍如何使用plutil来操作数组。建议每次操作完成之后,使用-p命令来查看文件的变化,这样可以直观地看见他的前后变化,利于理解。

    创建数组

    怎么创建一个数组呢?我们可以上面提到的两种标识来做,比如:

    plutil -insert listStyle -xml "<array/>" example.plist
    plutil -insert listColor -json "[]" example.plist

    第一句创建一个叫做listStyle的数组,第二个创建一个叫做listColor的数组

    插入数组项

    plutil -insert listStyle.0 -string "Suite" example.plist
    plutil -insert listStyle.1 -string "Casual" example.plist
    plutil -insert listStyle.2 -string "Casual" example.plist
    plutil -insert listStyle.3 -string "Vibrant" example.plist

    上面我们依照顺序在listStyle数组中插入了四个字符串类型的数组项。从中可以看出,访问每个数组项的索引表达方式。

    plutil -insert listColor.0 -string "Red" example.plist
    plutil -insert listColor.1 -string "Green" example.plist
    plutil -insert listColor.0 -string "Orange" example.plist
    plutil -insert listColor.3 -string "Purple" example.plist

    上面的例子中,第一句在位置.0处插入了”Red”,.1出插入“Green”,而第三句又在.0处插入了”Orange”,那么结果是:

    listColor.0 = Orange
    listColor.1 = Red
    listColor.2 = Green

    也就是说插入点的数据顺序向后移动。

    删除数组项

    在删除前先看看example.plist文件中的数据。
    这个不难想象,根据前面的知识应该可猜到。比如我们删除listColor的”Green”一项,还记得它的位置吧,是.2,所以:

    plutil -remove listColor.2 example.plist

    删除后,在看看结果。

    替换数组项

    与前面的删除方法是类似的,比如我们上面的listStyle中有两个都是Casual,我们把.2的换成Elegant:

    plutil -replace listStyle.2 -string "Elegant" example.plist

    字典

    同上面介绍数组时的建议一样,还是掏多观察操作前后的变化

    创建字典

    怎么创建一个字典呢?我们可以上面提到的两种标识来做,比如:

    plutil -insert Employee -xml "<dict/>" example.plist

    第一句创建一个叫做Employee的字典对象,第二个创建一个叫做Education的字典对象

    插入字典项目

    plutil -insert Employee.LastName -string "Liu" example.plist
    plutil -insert Employee.FirstName -string "Tony" example.plist
    plutil -insert Employee.UserName -string "TonyLiu" example.plist
    plutil -insert Employee.Phone -string "1-222-890-1234" example.plist
    plutil -insert Employee.Password -data "5oiR5LiN5ZGK6K+J5L2gCg==" example.plist

    上面我们依照顺序在Employee字典中插入了五个各种类型的项目。从中可以看出,访问每个字典内各个项目的表达方式。

    删除数组项

    有了数组的经验,相信这里不会难倒读者了:

    plutil -remove Employee.Password example.plist

    替换数组项

    替换根式清澈熟路了:

    plutil -replace Employee.Phone -string "13911399999" example.plist

    后序

    命令比较

    简单说来:
    . defaults命令使用domain的概念访问plist文件,而且对命令的文件书写方式要求严格(比如不能带.plist),有的时候还找不到或无法访问非标准目录的,而且对复杂格式数据的鞋操作比较麻烦。但是它的读取操作确比plutil简单多了。
    . plutil对于复杂格式的写操作很直观,很类似于对类的操作,而且文件名也是直截了当,就是读数据功能太弱。
    . PlistBuddy可以说具有前面两者的有点,避免了它们各自的缺点,书写也方便。但是对于系统参数的plist文件操作,还是使用Defaults命令号,因为它会通知系统服务该参数文件已经修改,而PlistBuddy则不会。

    参考

    [JSON介绍] http://www.json.org/
    [ISO8601时间格式] https://en.wikipedia.org/wiki/ISO_8601



沪ICP备19023445号-2号
友情链接