Shell-Script

全域搜尋+替換,但僅在測試通過的情況下

  • May 23, 2022

我想對文件目錄進行全域搜尋和替換。有多種方法可以做到這一點(許多編輯器,sed+find),但我有一個額外的要求。我希望,對於每個可能的替換都執行一個 shell 腳本,並且只有在腳本通過時才保留更改。

舉個例子,假設我決定在我的 Rust 程式碼中過多地使用 ‘pub’,並且想嘗試讓我的程式碼“不那麼公開”。

我可以執行:sed -e 's/pub//g' -i $(find . -name "*.rs")刪除所有出現的pub,但其中一些是必要的,所以我想嘗試一次刪除pubs ,cargo check在每一個之後執行。

您的描述說您必須測試任何單個替換並保留或回滾。因此,您可以就地進行修改,測試並在失敗的情況下恢復備份文件,在成功的情況下不執行任何操作。

此外,您必須跟踪發生的情況,以免再次測試相同的被拒絕更改。假設模式可能在一行中出現一次,您可以對一個文件使用類似這樣的內容:

line_numbers=( $(sed -n '/pub/=' "$1") )

for i in "${line_numbers[@]}"; do
   sed -i.old "${i}s/pub//" "$1" && run_test || mv "$1.old" "$1"
done

我們只儲存出現的行號,以便我們為每個案例測試一次。第一個sed類似於grep -n只獲取行號。如果沒有匹配項,則以下循環將執行零次。第二個sed是只替換特定的行號$i。雙引號用於將變數擴展為 sed 表達式。

並為您的文件執行它:

find . -type f -name '*.rs' -exec sh script.sh {} \;

此外,您必須清理所有*.old備份文件,並選擇目標目錄中不存在的備份副檔名。

請注意,根據您的文件結構和模式的頻率以及run_test您執行的實際情況,這可能會很慢,因為我們呼叫了許多程序。在執行任何東西之前,還要始終確保您有良好的數據備份。

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