Shell

如果 sed 中包含正則表達式,如何跳過文件?

  • February 21, 2014

我目前使用以下簡化命令刪除尾隨空格並在需要時在文件末尾添加換行符

find . -type f -exec sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' {} \+

正如您很快就會看到的,這有兩個問題:它會更改二進製文件,並且會在文件末尾添加一個換行符,並帶有␍␊ 行分隔符。這些修改在送出等時很容易撤消或跳過git gui,但我想盡量減少*還原的數量。為此:

如果任何行與正則表達式匹配,有沒有辦法跳過整個文件?sed**

  • 我知道可能存在沒有 ␀ 字元的二進製文件,並且可能存在故意混合換行符或 ␀ 的文件。但我正在尋找需要最少人工干預的解決方案。可以想像,我可以列出我想要操作的所有文件副檔名,但是這將是一個非常長的列表,必須不斷審查,並且由於名稱衝突,二進製文件仍然有可能漏掉。

複雜的解決方法

while IFS= read -r -d '' -u 9
do
   if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
   then
       sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' -- "$REPLY"
   else
       echo "Skipping $REPLY" >&2
   fi
done 9< <(find . -type f -print0)

如果您相信git對什麼是二進製文件的看法,您可以使用它git grep來獲取非二進製文件的列表。假設t.cpp是一個文本文件,並且ls是一個二進製文件,都簽入:

$ ls
t.cpp ls
$ git grep -I --name-only -e ''
t.cpp

-I選項意味著:

-I

不要匹配二進製文件中的模式。

將其與您的sed表達結合起來:

$ git grep -I --name-only -z -e '' | \
      xargs -0 sed -i.bk -e 's/[ \t]\+\(\r\?\)$/\1/;$a\'

-z/xargs -0幫助處理奇怪的文件名。)

查看git grep手冊頁以獲取其他有用的選項 ---no-index或者--cached可以根據您想要操作的文件集提供幫助。

引用自:https://unix.stackexchange.com/questions/36233