僅在必要時從文字檔案中刪除尾隨空格

僅在必要時從文字檔案中刪除尾隨空格

我正在使用刪除尾隨空格

sed -i 's/[ \t]*$//' *.txt

但是,此命令將重寫所有檔案。

有沒有一種方便的方法來判斷文字檔案中是否有尾隨空格並跳過那些沒有尾隨空格的?

答案1

您可以使用grepfirst 來查找是否有需要修改的行,儘管這在最壞的情況下仍然會讀取文件兩次(在只有最後一行需要修改的情況下):

for f in ./*.txt; do
    grep -q '[[:blank:]]$' "$f" &&
      sed -i 's/[[:blank:]]*$//' "$f"
done

答案2

一種方法可以如圖find/grep/sed所示:

find . -maxdepth 1 -type f -name '*.txt' \
  -exec grep -q '[[:blank:]]$' {} \; \
  -exec sed -Ei -e 's/[[:blank:]]+$//' {} +
  • 如果 1 在目前目錄中運行,則使用 -maxdepth 進行查找。
  • {} \; 指的是要傳遞到的檔案的名稱grep,並且\;正在轉義 shell 元字元分號,該分號是命令結束符號。我們逃避它,讓它到達-exec。你也可以寫為';'
  • {} + 現在您{}已經知道了,這+意味著您傳遞了盡可能多的檔案名sed(基本上,不是傳遞{}當前結果的單一檔案名,而是在呼叫之前累積要用作參數find的清單)。這使我們能夠最大限度地減少呼叫次數。{}sedsed

答案3

執行編輯,僅在存在差異時替換原始文件。

for file in *.txt
do
    sed 's/[ \t]*$//' < "$file" > "$file.tmp.$$" || continue
    cmp -s -- "$file" "$file.tmp.$$" ||
      cat < "$file.tmp.$$" > "$file" ||
      continue
    rm -f -- "$file.tmp.$$"
done

答案4

以下內容建立在羅艾瑪的想法在所有檔案上運行sed表達式,但只保留實際修改的檔案。

它透過減少sed調用來修改這一點:

printf '%s\0' ./*.txt |
xargs -0 sed -i.bak 's/[[:blank:]]$//

然後,您可以瀏覽這些*.txt文件,將它們與原始文件進行比較,然後選擇您想要保留的文件:

for name in ./*.txt; do
    if cmp -s "$name" "$name.bak"; then
        # keep original
        mv "$name.bak" "$name"
    else
        # keep modified
        rm "$name.bak"
    fi
done

或者,一次完成這兩項操作:

printf '%s\0' ./*.txt |
xargs -0 sh -c '
    sed -i.bak "s/[[:blank:]]$//" "$@"
    for name do
        if cmp -s "$name" "$name.bak"; then
            mv "$name.bak" "$name"
        else
            rm "$name.bak"
        fi
    done' sh

相關內容