我正在使用刪除尾隨空格
sed -i 's/[ \t]*$//' *.txt
但是,此命令將重寫所有檔案。
有沒有一種方便的方法來判斷文字檔案中是否有尾隨空格並跳過那些沒有尾隨空格的?
答案1
您可以使用grep
first 來查找是否有需要修改的行,儘管這在最壞的情況下仍然會讀取文件兩次(在只有最後一行需要修改的情況下):
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
的清單)。這使我們能夠最大限度地減少呼叫次數。{}
sed
sed
答案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