老胡的辦法:
Linux中提到替換,首先想到的就是sed命令。無論是單個檔案還是多個檔案,使用sed都可以利用正則表示式來匹配和替換響應的內容,針對題主的問題,老胡分析了幾種情況,下面一一進行說明:
單字串替換是最常見的情況,比如在當前目錄的一批檔案中,用“man”來替換“ager”。用sed命令來實現需要用到正則表示式操作:
正則表示式中,s/M/N/的含義是將M替換為N,g的含義是全域性搜尋。所以上面的正則表示式的的含義就是在全域性內搜尋字串“man”,並且替換為“ager”。
常見的很多文章使用的是類似
這樣的用法,其實這是不夠嚴謹的,如果*代表的檔名恰好是“--debug”這樣與sed的引數相同的名字,命令的執行就會出錯。所以這裡要使用“--”引數定界符,來標記其後的所有字串都不被視作引數。
有時候單獨使用sed可能比較難適用於一些特殊的情況,比如我只想對某個目錄下的所有子目錄中php型別的原始碼檔案進行查詢替換,單獨用sed就不好辦到了。一般這個時候需要與find搭配起來使用:
-exec <command> { } + 的作用是在find命令之後使用輸出的結果作為引數來執行後面的命令,等價於:
除了使用find之外,利用shell選項配置也可以用for迴圈來實現遞迴遍歷所有子目錄進行替換:
globstar是shell選項,開啟後就可以使用**萬用字元,**代表遞迴匹配多級目錄。最外面的圓括號是為這一段程式碼建立一個子shell,避免shopt會對全域性的shell環境造成影響。
例如:
可以實現批次字串查詢替換;
總結一下,批次替換多檔案字串的思路太多了,主要分為兩個步驟:首先要解決的是如何獲取檔案列表,sed本身就可以透過*訪問某目錄下的所有檔案,此外還可以使用find;其次就是使用何種正則表示式來實現更高效的替換。sed的用法可謂千變萬化,還是需要多多練習才好掌握。
老胡的辦法:
Linux中提到替換,首先想到的就是sed命令。無論是單個檔案還是多個檔案,使用sed都可以利用正則表示式來匹配和替換響應的內容,針對題主的問題,老胡分析了幾種情況,下面一一進行說明:
一、最常見的單字串替換單字串替換是最常見的情況,比如在當前目錄的一批檔案中,用“man”來替換“ager”。用sed命令來實現需要用到正則表示式操作:
sed -i -- "s/man/ager/g" *正則表示式中,s/M/N/的含義是將M替換為N,g的含義是全域性搜尋。所以上面的正則表示式的的含義就是在全域性內搜尋字串“man”,並且替換為“ager”。
常見的很多文章使用的是類似
sed -i "s/man/ager/g" *這樣的用法,其實這是不夠嚴謹的,如果*代表的檔名恰好是“--debug”這樣與sed的引數相同的名字,命令的執行就會出錯。所以這裡要使用“--”引數定界符,來標記其後的所有字串都不被視作引數。
二、find與sed搭配使用適配特殊情形有時候單獨使用sed可能比較難適用於一些特殊的情況,比如我只想對某個目錄下的所有子目錄中php型別的原始碼檔案進行查詢替換,單獨用sed就不好辦到了。一般這個時候需要與find搭配起來使用:
find . -name -type f -name "*.php" -exec sed -i "s/man/ager/g" {} +-exec <command> { } + 的作用是在find命令之後使用輸出的結果作為引數來執行後面的命令,等價於:
find . -name -type f -name "*.php" | xargs -I{} sed -i "s/man/ager/g" {}三、遞迴遍歷所有子目錄進行替換除了使用find之外,利用shell選項配置也可以用for迴圈來實現遞迴遍歷所有子目錄進行替換:
(shopt -s globstar dotglob; for file in **; doif [[ -w $file ]]; thensed -i -- "s/man/ager/g" "$file"fidone)globstar是shell選項,開啟後就可以使用**萬用字元,**代表遞迴匹配多級目錄。最外面的圓括號是為這一段程式碼建立一個子shell,避免shopt會對全域性的shell環境造成影響。
四、其他例如:
sed -i "s/A/B/g; s/C/D/g; s/E/F/g" file可以實現批次字串查詢替換;
總結一下,批次替換多檔案字串的思路太多了,主要分為兩個步驟:首先要解決的是如何獲取檔案列表,sed本身就可以透過*訪問某目錄下的所有檔案,此外還可以使用find;其次就是使用何種正則表示式來實現更高效的替換。sed的用法可謂千變萬化,還是需要多多練習才好掌握。