简体   繁体   English

如何查找和重命名多个文件

[英]How can i find and rename multiple files

I have multiple files in multiple directories and i have to rename these files from lowercase to uppercase;我在多个目录中有多个文件,我必须将这些文件从小写重命名为大写; the file extension may vary and needs to be in lowercase (should be renamed too for files with extensions in uppercase).文件扩展名可能会有所不同,并且需要小写(对于具有大写扩展名的文件也应该重命名)。

NB: I have rename version from util-linux on CentOS Linux7.注意:我在 CentOS Linux7 上renameutil-linux版本。

i tried this :我试过这个:

find /mydir -depth | xargs -n 1 rename -v 's/(.*)\/([^\/]*)/$1\/\U$2/' {} \;
find /mydir -depth | xargs -n 1 rename -v 's/(.*)\/([^\/]*)/$2\/\L$2/' {} \;

but it's not working it changes nothing and i have no output.但它不工作它没有任何改变,我没有输出。

Itried another solution :尝试了另一种解决方案:

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

this one partially works but transforms the files extensions to uppercase too.这个部分有效,但也将文件扩展名转换为大写。

Any suggestions on how to keep/transform the extensions to lowercase ?关于如何将扩展保留/转换为小写的任何建议?

Thank you!谢谢!

rename -independent solution (using find together with mv ) rename独立解决方案(将findmv一起使用)

You can rename all files in a directory with a following command:您可以使用以下命令重命名目录中的所有文件:

for i in $( ls | grep [A-Z] ); do mv -i $i `echo $i | tr 'A-Z' 'a-z'`; done

First part ( for i in $( ls | grep [AZ] ); ) looks for all uppercase characters and executes until all files are "scanned".第一部分( for i in $( ls | grep [AZ] ); )查找所有大写字符并执行,直到所有文件都被“扫描”。

Second part (``) turns all uppercase characters into lowercase ones.第二部分 (``) 将所有大写字符转换为小写字符。


Perl-based rename dependent solution基于 Perl 的rename依赖解决方案

rename -f 'y/A-Z/a-z/' *

This command changes uppercase characters to the lowercase ones.此命令将大写字符更改为小写字符。 -f option allows overwriting of existing files, but it is not necessary. -f选项允许覆盖现有文件,但这不是必需的。

Possible solution with Perl rename : Perl rename的可能解决方案:

find /mydir -depth -type f -exec rename -v 's/(.*\/)?([^.]*)/$1\U$2/' {} +

The commands in the question have several problems.问题中的命令有几个问题。

You seem to confuse the syntax of find 's -exec action and xargs .您似乎混淆了find-exec操作和xargs的语法。

find /mydir -depth -type f -exec rename -v 'substitution_command' {} \;
find /mydir -depth -type f| xargs -n 1 rename -v 'substitution_command'

The xargs version has problems in case a file name contains a space.如果文件名包含空格, xargs版本会出现问题。

If you replace \;如果你替换\; with + , multiple file names are passed to one invocation of rename .使用+ ,将多个文件名传递给一次rename调用。


The substitution command is only supported by the Perl version of the rename command.仅 Perl 版本的rename命令支持替换命令。 You might have to install this version.您可能必须安装此版本。 See Get the Perl rename utility instead of the built-in rename请参阅获取 Perl 重命名实用程序而不是内置重命名


The substitution did not work in my test.替换在我的测试中不起作用。 I successfully used我成功使用

rename -v 's/(.*\/)?([^.]*)/$1\U$2/' file ...

The first group (.*\/)?第一组(.*\/)? optionally matches a sequence of characters with a trailing / .可选地匹配带有尾随/的字符序列。 This is used to copy the directory unchanged.这用于复制未更改的目录。

The second group ([^.]*) matches a sequence of characters except .第二组([^.]*)匹配除 . 之外的字符序列. . .

This is the file name part before the first dot (if any) which will be converted to uppercase.这是第一个点(如果有)之前的文件名部分,它将被转换为大写。 In case the file name has more than one extension, all will remain unchanged, eg如果文件名有多个扩展名,则全部保持不变,例如
Path/To/Foo.Bar.Baz -> Path/To/FOO.Bar.Baz Path/To/Foo.Bar.Baz /Foo.Bar.Baz -> Path/To/FOO.Bar.Baz

suggesting a trick with awk that will generate all required mv commands:建议使用awk生成所有必需的mv命令的技巧:

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

Inspect the result, and run all mv commands together:检查结果,并一起运行所有mv命令:

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 script.awk explanation awk脚本script.awk解释

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; 
}

Testing:测试:

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

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

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