我有以下開頭的檔案和目錄“類別圖示-”在許多子目錄中。我正在嘗試將它們遞歸重命名為“類別-圖示-”。請注意我添加了缺失的“G”到類別和“s”在......的最後圖示。
我確實查看了大量有關重命名多個文件和目錄的其他問題,但無法使它們中的任何一個為我工作!
對答案的一些解釋將不勝感激。
編輯:這是我的目錄結構的範例:
test/cateory-icon-archery/cateory-icon-archery.png
[email protected]
test/cateory-icon-automotive/cateory-icon-automotive.png
[email protected]
答案1
由於您需要遞歸地執行此操作,find
因此 是最好使用的工具。若要變更名稱,您可以sh
在-exec
通話中使用。這是一個例子:
find /some/path -name 'cateory-icon' -exec sh -c 'mv "$1" "${1%/*}/category-icon-${1#cateory-icon-*}"' -- {} \;
擴充${1#cateory-icon-*}
獲取 後的檔名cateory-icon
。
答案2
在 zsh 中,將以下內容放入您的.zshrc
(或在命令列中執行這些內容一次性):
autoload zmv
alias zcp='zmv -C'
alias zln='zmv -L'
這zmv
功能與 zsh 結合通配符和通配符功能允許輕鬆的檔案重命名和複製。這裡有幾種方法可以做你想做的事:
zmv '(**/)cateory-icon-(*)' '${1}category-icons-$2'
zmv -w '**/cateory-icon-*' '${1}category-icons-$2'
zmv '**/cateory-icon-(*)' '$f:h/category-icons-$1'
zsh 一些功能說明:
**/
遞歸匹配子目錄中的檔案。- 來源表達式中的括號指定群組。
$NUM
或${NUM}
在替換表達式中被替換為第 NUM 群組中包含的原始名稱部分。 - 周圍的括號
**
有點奇怪:你只能將它們放在周圍**/
,不能多也不能少。 - 自動
-w
將zmv
每個通配符放入群組中的選項(對於**
,它是**/
群組中的部分,尾隨/
)。 $f
替換中的意思是整個原始檔名。$VAR:h
表示 的目錄部分$VAR
。這通常$VAR
直到最後一個/
,但所有邊緣情況(foo
、foo/
、/
、 …)都會正確處理。基本名稱可用作$VAR:t
.
答案3
使用 Perl 實現最大的可移植性:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy qw(move);
my $new_name;
finddepth( sub {
if(/cateory-icon/){
($new_name = $File::Find::name) =~ s{.*/\Kcateory-icon}{category-icons};
move $File::Find::name => $new_name;
}
},
'.')
解釋
- 這利用了 2 個 Perl 核心模組:
File::Find
用於目錄樹的遞歸遍歷和File::Copy
目錄的遞歸複製/移動。 - 此
finddepth
函數 (fromFile::Find
) 遍歷作為其第二個參數提供的目錄列表(.
在本例中是當前目錄;根據需要進行修改)。 - 第一個參數
finddepth
是一個子例程引用,finddepth
在樹中遇到的每個檔案都會執行該子例程引用。 - 我們透過一個條件開始這個子程式
if
:如果它符合的檔案名稱包含模式cateory-icon
,那麼我們透過進行所需的更正來形成新名稱,並使用函數move
(fromFile::Copy
) 將目前名稱修改為新名稱名稱。
免責聲明
該代碼未經測試。首先在虛擬目錄樹上嘗試!