我有以以下开头的文件和目录“类别图标-”在许多子目录中。我正在尝试将它们递归重命名为“类别-图标-”。请注意我添加了缺失的“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
) 将当前名称修改为新名称姓名。
免责声明
该代码未经测试。首先在虚拟目录树上尝试一下!