我有這樣的文件結構:
- 00000010
- 000000001.文件1
- 000000001.文件2
- 00000020
- 00000003.文件1
- 00000003.文件2
- 00000003.file3
- …
因此,存在名稱為 8 位數字的資料夾,其中包含一個或多個名稱以 8 位數字開頭的檔案。但這些檔名——比如說——不同步。所以現在我嘗試在 bash 中遞歸地重命名它們以存檔:
- 00000010
- 000000010.文件1
- 000000010.文件2
- 00000020
- 00000020.文件1
- 00000020.文件2
- 00000020.file3
- …
我的腳本確實看起來像:
#! /bin/bash
find * -maxdepth 1 -name "*" -type d | while read -r dir
do
rename 's/$dir\/[0-9]{8}/$dir/' *
done
但這不起作用並給出類似錯誤
全域符號「$dir」需要在 (eval 1) 第 1 行顯示明確套件名稱。
我怎麼才能編寫它來根據資料夾名稱重命名文件?
謝謝你的幫忙!
答案1
從我了解到的另一個答案中,我必須使用
rename "s/$dir\/[0-9]{8}/$dir\/$dir/" $dir/*
以防萬一有人遇到同樣的問題...
答案2
我真的不喜歡$dir
插入到模式中的答案。例如,如果目錄包含被解釋為特殊正規表示式標記的字符,則可能會導致意外結果。
我寧願直接在模式中匹配文件,不需要循環目錄,只使用常規的 glob。
rename 's#([^/]+)/[^/]+(\.file[0-9]+)$#$1/$1$2#' base_directory/*/*
其中 glob 命中目錄中的各個檔案(甚至可以指定為base_directory/*/*.file*
, 或類似的,但在這裡應該不重要)。
請注意,這是完整的命令,不需要構造find
。
- 我使用
#
作為分隔符號而不是“常規”,/
以避免必須在模式中轉義。 - 我捕獲“不是目錄分隔符”的(貪婪)群組,後面跟著目錄分隔符,然後是檔案名稱和行結束符。這使得第一個捕獲組成為每個檔案的父目錄。
- 檔案名稱的第一部分將被丟棄,但結尾部分將保留序數後綴。
我選擇使用更通用的方法,而不是假設文件都是 8 個字元長,但真正的區別是我既不需要構造find
也不需要將$dir
變數塞入(可能不安全)正規表示式環境中。