簡體   English   中英

如何“ for f循環”並刪除空白行

[英]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 +下一行並獲得結果

  1. 沒有空間
  2. 每個info.plist后的空格

預期結果:

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嘗試打印第三個字段(某種),但那里沒有任何相關內容。

為了解決這個問題,您需要停止使用grepawk ,並使用一個實際上了解屬性列表格式(所有形式)的工具,例如defaultsPlistBuddy 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/133219https://mywiki.wooledge.org/Quoteshttp://mywiki.wooledge.org/DontReadLinesWithFor他們解決一些腳本的其他問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM