[英]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.