Bash
基於 CSV 文件形式的字典重命名文件夾?
我將非常詳細地描述這個問題,因為我了解到只談論我已經確定的特定子問題會導致錯過機會……所以我會在前面放一個 tl;dr:有一組文件夾需要根據 CSV 文件中的映射重命名。
文件夾名稱遵循以下模式:
[[:alpha:]]*[[:digit:]]*_[[:alnum:]]*
中間的數字是相關的,並指定文件夾應具有的新名稱。所以我可以執行以下 sed 命令來提取我感興趣的文件夾名部分。
sed 's/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/'
所以我們可能有一個名為的文件夾
deptA100257_2bfde391c6af30fde3fca94b07bc8e7c
,可以提取相關的 ID100257
。然後我需要根據以下 CSV 重命名文件夾:63;9961 63;100257
新名稱在左側,舊名稱的 ID 在右側。因此,上面範例中的文件夾應重命名為
63
.第一個明顯的問題:多個 ID 可能映射到一個名稱。我會通過預先創建所有“新”文件夾並複製文件夾內容來解決這個問題。
我可以使用 Python 或其他任何東西,甚至可能是一些 bash 循環來破解它。但有件事告訴我,這種操作(根據文件替換)在核心上並不少見。所以在重新發明輪子之前…
我更喜歡使用標準 *NIX 外殼和工具(尤其是 bash 或 zsh)的解決方案,而不是像 Perl、Ruby、Python 這樣的“外部”語言……但最後我或多或少地在尋找一種“智能”方法,如果有是一個很好的 Ruby 單線器,可以完成工作,我可以接受。
我會
find
用來獲取文件夾名稱,用sed
grep 解析它們,並複制相應的 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 的行。這樣您就可以避免同時匹配id1123
和123
id123
。