首頁>Club>
14
回覆列表
  • 1 # 產品經理老胡

    老胡的辦法:

    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的用法可謂千變萬化,還是需要多多練習才好掌握。

  • 中秋節和大豐收的關聯?
  • 為什麼現在有些父母要求子女的另一半不能是單親家庭?