繁体   English   中英

用于批量重命名文件的 Shell 脚本

[英]Shell Script for Bulk renaming of files

我想通过更改前缀来递归地重命名目录路径中的所有文件。

例如

XYZMyFile.h
XYZMyFile.m
XYZMyFile1.h
XYZMyFile1.m
XYZMyFile2.h
XYZMyFile2.m

ABCMyFile.h
ABCMyFile.m
ABCMyFile1.h
ABCMyFile1.m
ABCMyFile2.h
ABCMyFile2.m

这些文件位于具有多层的目录结构下。 有人可以帮我编写此批量任务的 shell 脚本吗?

一种不同的方法可能:

ls *.{h,m} | while read a; do n=ABC$(echo $a | sed -e 's/^XYZ//'); mv $a $n; done

说明:

ls *.{h,m} --> Find all files with .h or .m extension
n=ABC --> Add a ABC prefix to the file name
sed -e 's/^XYZ//' --> Removes the XYZ prefix from the file name
mv $a $n --> Performs the rename

首先设置globstar ,然后使用如下重命名:

# shopt -s globstar # This will cause '**' to expand to each and everything
# ls -R
.:
nXYZ1.c  nXYZ2.c  nXYZ3.c  subdir  XYZ1.m  XYZ2.m  XYZ3.m
nXYZ1.h  nXYZ2.h  nXYZ3.h  XYZ1.c  XYZ2.c  XYZ3.c
nXYZ1.m  nXYZ2.m  nXYZ3.m  XYZ1.h  XYZ2.h  XYZ3.h

./subdir:
nXYZ1.c  nXYZ1.m  nXYZ2.h  nXYZ3.c  nXYZ3.m  XYZ1.h  XYZ2.c  XYZ2.m  XYZ3.h
nXYZ1.h  nXYZ2.c  nXYZ2.m  nXYZ3.h  XYZ1.c   XYZ1.m  XYZ2.h  XYZ3.c  XYZ3.m
# rename 's/^XYZ(.*.[mh])$/ABC$1/;s/^([^\/]*\/)XYZ(.*.[mh])$/$1ABC$2/' **
# ls -R
.:
ABC1.h  ABC2.m  nXYZ1.c  nXYZ2.c  nXYZ3.c  subdir  XYZ3.c
ABC1.m  ABC3.h  nXYZ1.h  nXYZ2.h  nXYZ3.h  XYZ1.c
ABC2.h  ABC3.m  nXYZ1.m  nXYZ2.m  nXYZ3.m  XYZ2.c

./subdir:
ABC1.h  ABC2.h  ABC3.h  nXYZ1.c  nXYZ1.m  nXYZ2.h  nXYZ3.c  nXYZ3.m  XYZ2.c
ABC1.m  ABC2.m  ABC3.m  nXYZ1.h  nXYZ2.c  nXYZ2.m  nXYZ3.h  XYZ1.c   XYZ3.c
# shopt -u globstar # Unset gobstar

这可能是实现目标的最简单方法。


注意1:这里我没有像您注意到的nXYZnABC更改为nABC 如果要更改它们,则简化的rename命令将是

rename 's/XYZ(.*.[mh])$/ABC$1/' **

注2:这个问题没有提到多次出现XYZ 所以在这方面什么也没做。

对于非递归,您可以使用rename这是一个perl脚本:

rename -v -n 's/^.+(?=MyFile)/what-you-want/' *.{h,m}  

测试

 dir >  ls | cat -n
     1  XYZMyFile1.h
     2  XYZMyFile1.m
     3  XYZMyFile.h
     4  XYZMyFile.m
 dir >  
 dir >  rename -v -n 's/^.+(?=MyFile)/what-you-want/' *.{h,m}
rename(XYZMyFile1.h, what-you-wantMyFile1.h)
rename(XYZMyFile1.m, what-you-wantMyFile1.m)
rename(XYZMyFile.h, what-you-wantMyFile.h)
rename(XYZMyFile.m, what-you-wantMyFile.m)
 dir >  

对于递归,使用find + 这个命令


如果您无权访问rename ,则可以直接使用perl ,如下所示:

perl -le '($old=$_) && s/^xzy/abc/g && rename($old,$_) for <*.[mh]>'

这是一个屏幕截图

在此处输入图片说明


使用renrem ,这是我使用 C++ 开发的 CLI,专门用于重命名

人行

轻松findrename (/usr/bin 中的二进制文件,而不是提到的 Perl 函数)

是的,已经有一个命令可以非递归地执行此操作。

rename XYZ ABC XYZ*

rename --help

Usage:
 rename [options] expression replacement file...

Options:
 -v, --verbose    explain what is being done
 -s, --symlink    act on symlink target

 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see rename(1).

编辑:错过了问题的“多层目录”部分,b/c 有点乱。 添加查找。

最容易记住:

find . -type f -name "*.pdf" -exec rename XYZ ABC {} \;

完成速度可能更快:

find . -type d -not -path "*/\.*" -not -name ".*" -exec rename XYZ ABC {}/*.pdf \;

我不确定如何比一个命令行代码更容易。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM