macOS: 使用新版plutil命令操作Plist文件更方便
Posted afatgoat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了macOS: 使用新版plutil命令操作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
以上是关于macOS: 使用新版plutil命令操作Plist文件更方便的主要内容,如果未能解决你的问题,请参考以下文章
带有 plutil 的 CFBundleDisplayName 中的空间
macOS新版本终于删掉自带Python2,这波操作连Python死忠粉都叫好