首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何找到多个文件并重命名

问如何找到多个文件并重命名
EN

Stack Overflow用户
提问于 2022-05-18 15:34:47
回答 3查看 123关注 0票数 1

我在多个目录中有多个文件,我必须将这些文件从小写重命名为大写;文件扩展名可能会有所不同,需要用小写表示(对于扩展名为大写的文件,也应该重命名)。

注:我有rename版的util-linux on CentOS Linux7。

我试过这个:

代码语言:javascript
复制
find /mydir -depth | xargs -n 1 rename -v 's/(.*)\/([^\/]*)/$1\/\U$2/' {} \;
find /mydir -depth | xargs -n 1 rename -v 's/(.*)\/([^\/]*)/$2\/\L$2/' {} \;

但它不起作用,没有任何变化,我也没有输出。

我尝试了另一个解决方案:

代码语言:javascript
复制
for SRC in `find my_root_dir -depth`
do
   DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
   if [ "${SRC}" != "${DST}" ]
   then
      [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
   fi
done

这个部分工作,但将文件扩展名转换为大写。

对于如何将扩展保持/转换为小写,有什么建议吗?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-05-18 19:08:37

使用Perl rename的可能解决方案

代码语言:javascript
复制
find /mydir -depth -type f -exec rename -v 's/(.*\/)?([^.]*)/$1\U$2/' {} +

问题中的命令有几个问题。

您似乎混淆了find的-exec操作和xargs的语法。

代码语言:javascript
复制
find /mydir -depth -type f -exec rename -v 'substitution_command' {} \;
代码语言:javascript
复制
find /mydir -depth -type f| xargs -n 1 rename -v 'substitution_command'

如果文件名包含空格,则xargs版本会出现问题。

如果将\;替换为+,则将多个文件名传递给对rename的一次调用。

rename命令的Perl版本只支持替换命令。您可能需要安装此版本。请参阅Get the Perl rename utility instead of the built-in rename

这个替代在我的测试中不起作用。我成功地使用了

代码语言:javascript
复制
rename -v 's/(.*\/)?([^.]*)/$1\U$2/' file ...

第一组(.*\/)?可选择地将字符序列与尾随/匹配。此操作用于复制目录,未作更改。

第二组([^.]*)匹配除.以外的一系列字符。

这是第一个点(如果有的话)之前的文件名部分,它将被转换为大写。如果文件名有多个扩展名,则所有文件名都将保持不变。

Path/To/Foo.Bar.Baz -> Path/To/FOO.Bar.Baz

票数 1
EN

Stack Overflow用户

发布于 2022-05-18 17:07:30

rename-independent解决方案(使用find和mv)

可以使用以下命令重命名目录中的所有文件:

代码语言:javascript
复制
for i in $( ls | grep [A-Z] ); do mv -i $i `echo $i | tr 'A-Z' 'a-z'`; done

第一部分(for i in $( ls | grep [A-Z] );)查找所有大写字符并执行,直到所有文件都被“扫描”。

第二部分()将所有大写字符转换为小写字符。

基于Perl的rename依赖解决方案

代码语言:javascript
复制
rename -f 'y/A-Z/a-z/' *

此命令将大写字符更改为小写字符。-f选项允许覆盖现有文件,但并不是必需的。

票数 1
EN

Stack Overflow用户

发布于 2022-05-18 23:34:59

建议使用awk来生成所有所需的mv命令:

代码语言:javascript
复制
awk '{f=$0;split($NF,a,".");$NF=tolower(a[1])"."toupper(a[2]);print "mv "f" "$0}' FS=/ OFS=/ <<< $(find . -type f)

检查结果,并一起运行所有mv命令:

代码语言:javascript
复制
bash <<< $(awk '{f=$0;split($NF,a,".");$NF=tolower(a[1])"."toupper(a[2]);print "mv "f" "$0}' FS=/ OFS=/ <<< $(find . -type f))

awk脚本script.awk解释

代码语言:javascript
复制
BEGIN { # preprocessing configuration
  FS="/"; # set awk field separtor to /
  OFS="/"; # set awk output field separtor to /
}
{ # for each line in input list
  filePath = $0; # save the whole filePath in variable
  # fileName is contained in last field $NF
  # split fileName by "." to head: splitedFileNameArr[1] and tail: splitedFileNameArr[2]
  split($NF,splitedFileNameArr,"."); 
  # recreate fileName from lowercase(head) "." uppercase(tail)
  $NF = tolower(splitedFileNameArr[1]) "." toupper(splitedFileNameArr[2]);
  # generate a "mv" command from original filePath and regenerated fileName
  print "mv "filePath" "$0; 
}

测试:

代码语言:javascript
复制
mkdir {a1,B2}/{A1,b2} -p; touch {a1,B2}/{A1,b2}/{A,b}{b,C}.{c,D}{d,C}
find . -type f

./a1/A1/Ab.cC
./a1/A1/Ab.cd
./a1/A1/Ab.DC
./a1/A1/Ab.Dd
./B2/b2/AC.DC
./B2/b2/AC.Dd
.....
./B2/b2/bC.cd
./B2/b2/bC.DC
./B2/b2/bC.Dd

awk -f script.awk <<< $(find . -type f)

.....
mv ./a1/b2/Ab.cd ./a1/b2/ab.CD
mv ./a1/b2/Ab.DC ./a1/b2/ab.DC
mv ./a1/b2/Ab.Dd ./a1/b2/ab.DD
mv ./B2/A1/bC.Dd ./B2/A1/bc.DD
.....
mv ./B2/b2/bC.DC ./B2/b2/bc.DC
mv ./B2/b2/bC.Dd ./B2/b2/bc.DD

bash <<< $(awk -f script.awk <<< $(find . -type f))
find . -type f
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72292083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档