我希望能够做到这一点:重命名string1
为string3
并添加string2
到开头。例如,如果找到字符串 Fish 并且 Great_ = string2,则将 Fish 重命名为 Great_Bear。
到目前为止我有这个:
ls | sed s'/\(.*\)\(string1\)\(.*\)/mv \"&\" \"\1string3\" /' | bash
这完成了当前目录的工作。
ls -d $PWD/**/* | sed s'/\(.*\)\(string1\)\(.*\)/mv \"&\" \"\1string3\" /' | bash
这只在子目录中有效,而不在脚本所在的目录中有效。
我还想知道如何添加string2
到文件名的开头。
答案1
我会使用rename
简单*/*
匹配,而不是 globstar 模式。
rename 's|([^/]+)/(.+)|$1/$1_$2|' */* -vn
我们匹配一个目录,然后匹配它包含的内容。这比 globstar 更安全,因为我们不想递归太远。
最后-n
却停止了正在做任何东西。它只会显示给你。当你确定它是正确的时候,删除它。这里有一个小测试工具:
$ mkdir -p test/test{1..3} && touch test/test{1..3}/file{1..3}
$ cd test
$ rename 's|([^/]+)/(.+)|$1/$1_$2|' */* -vn
test1/file1 renamed as test1/test1_file1
test1/file2 renamed as test1/test1_file2
test1/file3 renamed as test1/test1_file3
test2/file1 renamed as test2/test2_file1
test2/file2 renamed as test2/test2_file2
test2/file3 renamed as test2/test2_file3
test3/file1 renamed as test3/test3_file1
test3/file2 renamed as test3/test3_file2
test3/file3 renamed as test3/test3_file3
答案2
这应该可以解决问题:
find . -type f -exec rename -n 's/(.*)\/(.*)string1(.*)/$1\/string3$2string2$3/' {} +
find . -type f -exec
{} +
:在当前工作目录的层次结构中递归搜索文件,并执行扩展到结果列表的其余命令行;rename -n 's/(.*)\/(.*)string1(.*)/$1\/string3$2string2$3/' {} +
:匹配并将任意数量的任意字符分组,直到最后一次出现/
,匹配一个/
,匹配并将任意数量的任意字符分组,直到最后一次出现string1
,匹配string1
并将任意数量的任意字符分组;用第一个捕获组替换匹配项,后跟一个/
字符,后跟string3
第二个捕获组,后跟string2
第三个捕获组(-n
执行rename
试运行;将其删除以实际重命名文件)。
% tree
.
└── dir
├── string1_bar.jpg
├── string1_foobar.jpg
└── string1_foo.jpg
1 directory, 3 files
% find . -type f -exec rename -n 's/(.*)\/(.*)string1(.*)/$1\/string3$2string2$3/' {} +
rename(./dir/string1_foo.jpg, ./dir/string3string2_foo.jpg)
rename(./dir/string1_foobar.jpg, ./dir/string3string2_foobar.jpg)
rename(./dir/string1_bar.jpg, ./dir/string3string2_bar.jpg)