我正在连接到macOSX Shell,并运行bash命令来扫描info.plist并打印结果,但是,我得到了一些空白行
for f in $(find . -name 'Info.plist'); do grep -A 1 -e CFBundleIdentifier -e CFBundleVersion $f 2>/dev/null | awk -F "[<>]" '{print $3}'; done
for f in $(find . -name 'Info.plist'); do grep -A 1 -E 'CFBundleIdentifier|CFBundleVersion' $f 2>/dev/null | awk -F "[<>]" '{print $3}'; done
结果:
CFBundleIdentifier
com.apple.xcode.dsym.com.app.app1
CFBundleVersion
2.16.0.4386
CFBundleIdentifier
com.apple.xcode.dsym.app.app1Additions
CFBundleVersion
1
问题似乎出在Grep -e或-E上。如果我只做一个grep并使用-A 1打印下一行,我将没有任何空格
没有多次抱怨的结果:
for f in $(find . -name 'Info.plist'); do grep -A 1 CFBundleIdentifier $f 2>/dev/null | awk -F "[<>]" '{print $3}'; done
结果:
CFBundleIdentifier
com.apple.xcode.dsym.com.app.app1
CFBundleIdentifier
com.apple.xcode.dsym.app.app1Additions
我如何更好地扫描info.plist并打印CFBundleIdentifier +下一行和CFBundleIdentifier +下一行并得到结果
预期结果:
CFBundleIdentifier
com.apple.xcode.dsym.com.app.app1
CFBundleVersion
2.16.0.4386
<Actual real space>
CFBundleIdentifier
com.apple.xcode.dsym.app.app1Additions
CFBundleVersion
1
更新1:
添加完整的Info.plist进行审核
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.com.app.app1/string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>2.16.0</string>
<key>CFBundleVersion</key>
<string>2.16.0.4385</string>
</dict>
答案 0 :(得分:1)
我怀疑根本问题是某些Info.plist文件采用的是属性列表格式的二进制形式,而不是XML形式,因此grep
会打印出如下几行:
Binary file ./some/path/to/Info.plist matches
...,然后awk
尝试打印第三个字段(某种),但那里没有任何相关内容。
为了解决此问题,您需要停止使用grep
和awk
,并使用一种能够真正理解属性列表格式(所有形式)的工具,例如defaults
或PlistBuddy
。 defaults
在如何指定文件路径方面存在一些问题,因此我投票赞成PlistBuddy
。
此外,正如@chepner和@EdMorton指出的那样,在for
的输出上进行find
循环并不是处理文件名的安全方法,尤其是在macOS中,文件名中的空格很常见。 PlistBuddy
将很容易直接与find ... -exec
一起使用,但是由于您希望在每个文件后留一个空白行,因此更加复杂。可能最简单的方法是使用while read
循环(使用以空分隔的文件名来避免空格等问题):
find . -name 'Info.plist' -print0 |
while IFS= read -r -d '' file; do
/usr/libexec/PlistBuddy -c "print CFBundleIdentifier" -c "print :CFBundleVersion" "$file" 2>/dev/null
echo
done
请注意,这不会打印“ CFBundleIdentifier”和“ CFBundleVersion”行,而仅打印那些属性列表元素中的数据。如果要使用这些名称,则又要复杂一点,因为您必须测试plist中是否确实存在这些项目。
答案 1 :(得分:0)
空白行来自第三字段中没有任何内容的行。因此,请在awk
中进行检查。
for f in $(find . -name 'Info.plist'); do
grep -A 1 -E 'CFBundleIdentifier|CFBundleVersion' $f 2>/dev/null |
awk -F "[<>]" '$NF >= 3 {print $3}'
done
答案 2 :(得分:0)
您没有提供任何示例输入,因此这只是一个猜测,但您似乎只是想查找几个字符串,然后从包含该字符串的行及其后的行打印第三个字段。如果是这样,那就是:
find . -name 'Info.plist' -exec \
awk -F'[<>]' '/CFBundle(Identifier|Version)/{c=2} c&&c--{print $3}' {} +
如果您的find
不支持将+
作为参数,请改用\;
。
您可能想阅读https://unix.stackexchange.com/q/169716/133219,https://mywiki.wooledge.org/Quotes,http://mywiki.wooledge.org/DontReadLinesWithFor,因为它们解决了脚本中的其他一些问题。