Bash

基於 CSV 文件形式的字典重命名文件夾?

  • September 20, 2021

我將非常詳細地描述這個問題,因為我了解到只談論我已經確定的特定子問題會導致錯過機會……所以我會在前面放一個 tl;dr:有一組文件夾需要根據 CSV 文件中的映射重命名。

文件夾名稱遵循以下模式:

[[:alpha:]]*[[:digit:]]*_[[:alnum:]]*

中間的數字是相關的,並指定文件夾應具有的新名稱。所以我可以執行以下 sed 命令來提取我感興趣的文件夾名部分。

sed 's/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/'

所以我們可能有一個名為的文件夾deptA100257_2bfde391c6af30fde3fca94b07bc8e7c,可以提取相關的 ID 100257。然後我需要根據以下 CSV 重命名文件夾:

63;9961
63;100257

新名稱在左側,舊名稱的 ID 在右側。因此,上面範例中的文件夾應重命名為63.

第一個明顯的問題:多個 ID 可能映射到一個名稱。我會通過預先創建所有“新”文件夾並複製文件夾內容來解決這個問題。

我可以使用 Python 或其他任何東西,甚至可能是一些 bash 循環來破解它。但有件事告訴我,這種操作(根據文件替換)在核心上並不少見。所以在重新發明輪子之前…

我更喜歡使用標準 *NIX 外殼和工具(尤其是 bash 或 zsh)的解決方案,而不是像 Perl、Ruby、Python 這樣的“外部”語言……但最後我或多或少地在尋找一種“智能”方法,如果有是一個很好的 Ruby 單線器,可以完成工作,我可以接受。

我會find用來獲取文件夾名稱,用sedgrep 解析它們,並複制相應的 id 並複制內容:

$ find . -mindepth 1 -type d | while read dir; do 
  id=$(echo "$dir" | sed 's/\.\/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/'); 
  new_name=$(grep -w "$id" names.csv | cut -d ';' -f 1); 
  mkdir -p "$new_name" && mv -rv "$dir"/* "$new_name"/ && rmdir "$dir"; 
done

訣竅是

  • 使用mkdir -p它將創建目錄並在它存在時靜默退出。
  • 在 csv 文件上使用grep -w以僅獲取那些包含以非單詞字元為邊界的整個 ID 的行。這樣您就可以避免同時匹配id1123123id 123

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