使用子目录和当前目录中的字符串替换文件名的一部分

使用子目录和当前目录中的字符串替换文件名的一部分

我希望能够做到这一点:重命名string1string3并添加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)

相关内容