簡體   English   中英

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

[英]How can i find and rename multiple files

我在多個目錄中有多個文件,我必須將這些文件從小寫重命名為大寫; 文件擴展名可能會有所不同,並且需要小寫(對於具有大寫擴展名的文件也應該重命名)。

注意:我在 CentOS Linux7 上renameutil-linux版本。

我試過這個:

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

但它不工作它沒有任何改變,我沒有輸出。

嘗試了另一種解決方案:

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

這個部分有效,但也將文件擴展名轉換為大寫。

關於如何將擴展保留/轉換為小寫的任何建議?

謝謝!

rename獨立解決方案(將findmv一起使用)

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

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

第一部分( for i in $( ls | grep [AZ] ); )查找所有大寫字符並執行,直到所有文件都被“掃描”。

第二部分 (``) 將所有大寫字符轉換為小寫字符。


基於 Perl 的rename依賴解決方案

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

此命令將大寫字符更改為小寫字符。 -f選項允許覆蓋現有文件,但這不是必需的。

Perl rename的可能解決方案:

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

問題中的命令有幾個問題。

您似乎混淆了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'

如果文件名包含空格, xargs版本會出現問題。

如果你替換\; 使用+ ,將多個文件名傳遞給一次rename調用。


僅 Perl 版本的rename命令支持替換命令。 您可能必須安裝此版本。 請參閱獲取 Perl 重命名實用程序而不是內置重命名


替換在我的測試中不起作用。 我成功使用

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

第一組(.*\/)? 可選地匹配帶有尾隨/的字符序列。 這用於復制未更改的目錄。

第二組([^.]*)匹配除 . 之外的字符序列. .

這是第一個點(如果有)之前的文件名部分,它將被轉換為大寫。 如果文件名有多個擴展名,則全部保持不變,例如
Path/To/Foo.Bar.Baz /Foo.Bar.Baz -> Path/To/FOO.Bar.Baz

建議使用awk生成所有必需的mv命令的技巧:

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

檢查結果,並一起運行所有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.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; 
}

測試:

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