Bash读取Plist数组元素无法仅返回字符串问题
从Plist数组提取纯字符串内容
问题场景
需要从Plist文件中读取数组,并提取数组元素的纯字符串内容。示例Plist文件如下:
<?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> <key>Entitlements</key> <array> <string>User;Domain;Group</string> </array> </dict> </plist>
当前使用的Bash代码:
#!/bin/bash entitlements=$(defaults read /Library/Preferences/com.company.plist Entitlements) for i in "${entitlements[@]}" do echo "$i" done
运行后返回结果(包含数组括号和多余格式):
( "User;Domain;Group" )
期望仅返回:
"User;Domain;Group"
环境:GNU bash, version 3.2.57(1)-release (arm64-apple-darwin22)
解决方案
方法1:用awk过滤defaults输出
直接过滤defaults返回的内容,提取目标行:
#!/bin/bash entitlements=$(defaults read /Library/Preferences/com.company.plist Entitlements | awk '/^ "/ {print $0}') echo "$entitlements"
原理:匹配以四个空格加双引号开头的行,直接输出该行内容。
方法2:用plutil工具(更可靠)
plutil是macOS自带的Plist处理工具,支持直接提取指定路径的元素:
#!/bin/bash # 提取数组第一个元素的纯字符串,再加上双引号 entitlement=$(plutil -extract Entitlements.0 raw /Library/Preferences/com.company.plist) echo "\"$entitlement\""
原理:-extract Entitlements.0 raw直接定位数组的第一个元素(索引从0开始),raw模式返回纯字符串,最后手动添加双引号匹配期望格式。
方法3:逐行读取过滤(适配Bash 3.2)
因为Bash 3.2没有readarray,可以用while read逐行处理输出:
#!/bin/bash defaults read /Library/Preferences/com.company.plist Entitlements | while read -r line; do if [[ "$line" =~ ^\ \ \ \ \" ]]; then echo "$line" fi done
原理:逐行读取defaults的输出,匹配符合格式的目标行并输出。
内容的提问来源于stack exchange,提问作者PhillyPhoto
相关产品推荐
相关产品推荐

