[英]how to 'for f loop' and remove blank lines
我正在连接到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>
我怀疑根本问题是某些Info.plist文件采用的是属性列表格式的二进制形式,而不是XML形式,因此grep
会打印如下几行:
Binary file ./some/path/to/Info.plist matches
...然后awk
尝试打印第三个字段(某种),但那里没有任何相关内容。
为了解决这个问题,您需要停止使用grep
和awk
,并使用一个实际上了解属性列表格式(所有形式)的工具,例如defaults
或PlistBuddy
。 defaults
在如何指定文件路径方面存在一些问题,因此我将投票给PlistBuddy
。
而且,正如@chepner和@EdMorton指出的那样,在find
的输出上for
循环不是处理文件名的安全方法,尤其是在macOS中,文件名中的空格很常见。 PlistBuddy
将很容易直接与find ... -exec
一起使用,但是由于您希望在每个文件后PlistBuddy
一个空白行,因此更加复杂。 可能最简单的方法是使用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中是否确实存在这些项目。
空行来自第三个字段中没有任何内容的行。 因此,请在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
您没有提供任何示例输入,因此这只是一个猜测,但您似乎只是想查找几个字符串,然后从包含该字符串的行及其后的行打印第三个字段。 如果是这样,那就是:
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他们解决一些脚本的其他问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.