Bash

使用模式和替換列表遞歸地重命名文件

  • April 15, 2017

我有以下文件結構:

  • 一些目錄

    • 一些文件.txt
    • 這裡的另一個文件.log
    • 又一個文件.mp3
  • 另一個目錄

    • 與其他一些 file.txt
  • 根級別的文件.txt

  • root level.ext 上的另一個文件

我現在要做的是執行一個小腳本,該腳本將另一個文件作為輸入,其中包含某種類型的模式/替換對,以根據它們遞歸地重命名這些文件。這樣每個“another”(不區分大小寫)都被替換為“foo”,或者每個“some”被替換為“bar”。

我已經嘗試了很多迭代文件和讀取所述輸入文件的方法,但是沒有任何工作像它應該的那樣工作,我最終設法不小心覆蓋了我的測試腳本。但是有很多ls, while,sedmv在使用中。

我自己無法解決的兩件事是如何處理文件名中的空格以及如何不處理在之前的模式匹配中已經重命名的文件。

也許你能指出我正確的方向?

TOP="`pwd -P`" \
find . -type d -exec sh -c '
  for d
  do
     cd "$d" && \
        find . ! -name . -prune -type f -exec sh -c '\''
           while IFS=\; read -r pat repl
           do
              rename "s/$pat/$repl/g" "$@"
              N=$#
              for unmoved
              do
                 if [ -f "$unmoved" ]
                 then
                    set X ${1+"$@"} "$unmoved"
                    shift
                 fi
              done
              shift "$N"
              case $# in 0 ) break ;; esac
           done < patterns.csv
        '\'' x \{\} +
     cd "$TOP"
  done
' x {} +
  • 僅設置find到網路目錄並sh一口氣將它們關閉。這最大限度地減少了呼叫的次數sh
  • find在每個目錄中設置網路文件regular,深度級別僅為 1,並將它們提供sh給 gulp。這最大限度地減少了rename實用程序被呼叫的次數。
  • 設置一個while循環來讀入各種pattern <-> replacement對並將它們應用於所有regular文件。
  • 在處理過程中,我們rename會記錄處理後文件是否仍然存在。如果我們發現一個文件仍然存在,那麼這意味著,由於某種原因,它不能被重命名,因此將在下一次迭代中嘗試。OTOH,如果文件已成功重命名,那麼我們不會通過將其從命令行參數列表中刪除來對該文件應用下一次迭代。rename``pat/repl``pat/repl

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