如何重命名多个文件夹中的多个文件?
How to rename multiple files in several folders?
我想通过'*doc*'重命名多个文件夹中文件名包含'*file*'的所有文件。我试过了
find . -name "*file*" -exec mv {} `echo {} | sed "s/file/doc/"` \;
但出现错误(见下文)。
~$ ls
my_file_1.txt my_file_2.txt my_file_3.txt
~$ find . -name "*file*"
./my_file_1.txt
./my_file_3.txt
./my_file_2.txt
~$ echo my_file_1.txt | sed "s/file/doc/"
my_doc_1.txt
~$ find . -name "*file*" -exec echo {} \;
./my_file_1.txt
./my_file_3.txt
./my_file_2.txt
~$ find . -name "*file*" -exec mv {} `echo {} | sed "s/file/doc/"` \;
mv: './my_file_1.txt' and './my_file_1.txt' are the same file
mv: './my_file_3.txt' and './my_file_3.txt' are the same file
mv: './my_file_2.txt' and './my_file_2.txt' are the same file
非常感谢您的帮助!
有上千种方法,我会用 Perl 来做,像这样的东西会起作用:
find files -type f -name "file*" | perl -ne 'chomp; $f=$_; $f=~s/\/file/\/doc/; `mv $_ $f`;'
-ne
处理每行输入的内联脚本
chomp
清理一个换行符
$f
为新文件名,与旧文件名相同
s/\/file/\/doc/
将新文件名中的“/file”替换为“/doc”
mv $_ $f
通过 运行 带反引号的 OS 命令重命名文件
看看你有没有rename
命令。如果是perl
基础:
# -n is for testing, remove it for actual renaming
find -name '*file*' -exec rename -n 's/file/doc/' {} +
如果它不是基于 perl
,看看这是否有效:
# remove --no-act --verbose for actual renaming
find -name '*file*' -exec rename --no-act --verbose 'file' 'doc' {} +
您的解决方案的问题是 echo {} | sed "s/file/doc/"
在 find
命令的其余部分之前执行。我试图制作一个命令来证明这一点:
find . -name "." -exec date \; -exec echo `date; sleep 5` \;
当date
命令a从左到右执行时,日期是相等的。但是,第二个 date
和 sleep
在 find
开始第一个 date
.
之前执行
结果:
Wed Aug 25 22:33:43 XXX 2021
Wed Aug 25 22:33:38 XXX 2021
以下解决方案使用 print0
和 xargs -0
作为带换行符的文件名。 xargs
将 echo
mv
命令加上两个额外的斜杠。
sed
命令将找到斜杠,更改目标文件名。
sed
的结果被一个新的bash
shell.
解析
find . -name "*file1*" -print0 2>/dev/null |
xargs -0 -I {} echo mv '"{}"' //'"{}"' |
sed -r 's#//(.*)file(.*)#doc#' |
bash
我想通过'*doc*'重命名多个文件夹中文件名包含'*file*'的所有文件。我试过了
find . -name "*file*" -exec mv {} `echo {} | sed "s/file/doc/"` \;
但出现错误(见下文)。
~$ ls
my_file_1.txt my_file_2.txt my_file_3.txt
~$ find . -name "*file*"
./my_file_1.txt
./my_file_3.txt
./my_file_2.txt
~$ echo my_file_1.txt | sed "s/file/doc/"
my_doc_1.txt
~$ find . -name "*file*" -exec echo {} \;
./my_file_1.txt
./my_file_3.txt
./my_file_2.txt
~$ find . -name "*file*" -exec mv {} `echo {} | sed "s/file/doc/"` \;
mv: './my_file_1.txt' and './my_file_1.txt' are the same file
mv: './my_file_3.txt' and './my_file_3.txt' are the same file
mv: './my_file_2.txt' and './my_file_2.txt' are the same file
非常感谢您的帮助!
有上千种方法,我会用 Perl 来做,像这样的东西会起作用:
find files -type f -name "file*" | perl -ne 'chomp; $f=$_; $f=~s/\/file/\/doc/; `mv $_ $f`;'
-ne
处理每行输入的内联脚本chomp
清理一个换行符$f
为新文件名,与旧文件名相同s/\/file/\/doc/
将新文件名中的“/file”替换为“/doc”mv $_ $f
通过 运行 带反引号的 OS 命令重命名文件
看看你有没有rename
命令。如果是perl
基础:
# -n is for testing, remove it for actual renaming
find -name '*file*' -exec rename -n 's/file/doc/' {} +
如果它不是基于 perl
,看看这是否有效:
# remove --no-act --verbose for actual renaming
find -name '*file*' -exec rename --no-act --verbose 'file' 'doc' {} +
您的解决方案的问题是 echo {} | sed "s/file/doc/"
在 find
命令的其余部分之前执行。我试图制作一个命令来证明这一点:
find . -name "." -exec date \; -exec echo `date; sleep 5` \;
当date
命令a从左到右执行时,日期是相等的。但是,第二个 date
和 sleep
在 find
开始第一个 date
.
之前执行
结果:
Wed Aug 25 22:33:43 XXX 2021
Wed Aug 25 22:33:38 XXX 2021
以下解决方案使用 print0
和 xargs -0
作为带换行符的文件名。 xargs
将 echo
mv
命令加上两个额外的斜杠。
sed
命令将找到斜杠,更改目标文件名。
sed
的结果被一个新的bash
shell.
find . -name "*file1*" -print0 2>/dev/null |
xargs -0 -I {} echo mv '"{}"' //'"{}"' |
sed -r 's#//(.*)file(.*)#doc#' |
bash