bash脚本重命名目录中的所有文件?

我有一堆需要重新命名的文件。

file1.txt needs to be renamed to file1_file1.txt file2.avi needs to be renamed to file2_file2.avi 

正如你所看到的,我需要的是原始文件名。

有很多这些文件。

到目前为止,所有的答案都是:

  1. 需要一些非便携式工具
  2. 可怕地与包含空格或换行符的文件名打破
  3. 不递归,即不下降到子目录

这两个脚本解决了所有这些问题。

Bash 2.X / 3.X

 #!/bin/bash while IFS= read -r -d $'\0' file; do dirname="${file%/*}/" basename="${file:${#dirname}}" echo mv "$file" "$dirname${basename%.*}_$basename" done < <(find . -type f -print0) 

Bash 4.X

 #!/bin/bash shopt -s globstar for file in ./**; do if [[ -f "$file" ]]; then dirname="${file%/*}/" basename="${file:${#dirname}}" echo mv "$file" "$dirname${basename%.*}_$basename" fi done 

一旦满意输出并重新运行,一定要从您选择的脚本中删除echo

编辑

修复了以前版本中没有正确处理路径名称的问题。

对于你的具体情况,你想使用mmv如下:

 pax> ll total 0 drwxr-xr-x+ 2 allachan None 0 Dec 24 09:47 . drwxrwxrwx+ 5 allachan None 0 Dec 24 09:39 .. -rw-r--r-- 1 allachan None 0 Dec 24 09:39 file1.txt -rw-r--r-- 1 allachan None 0 Dec 24 09:39 file2.avi pax> mmv '*.*' '#1_#1.#2' pax> ll total 0 drwxr-xr-x+ 2 allachan None 0 Dec 24 09:47 . drwxrwxrwx+ 5 allachan None 0 Dec 24 09:39 .. -rw-r--r-- 1 allachan None 0 Dec 24 09:39 file1_file1.txt -rw-r--r-- 1 allachan None 0 Dec 24 09:39 file2_file2.avi 

你需要知道通配符不是贪婪的。 这意味着文件abtxt将变成a_a.b.txt ,而不是a.b_a.b.txt

mmv程序是作为我的CygWin的一部分安装,但我不得不

 sudo apt-get install mmv 

在我的Ubuntu的盒子把它弄下来。 如果它不在你的标准发行版中,那么无论你使用的是哪个软件包管理器,都希望它可用。

如果出于某种原因,您不允许安装它,则必须使用其他bash中的其他解决方案中显示的-loop-type解决方案之一。 我更喜欢mmv的mmv但是你可能没有选择。

 for file in file*.* do [ -f "$file" ] && echo mv "$file" "${file%%.*}_$file" done 

递归的想法

 recurse() { for file in "$1"/*;do if [ -d "$file" ];then recurse "$file" else # check for relevant files # echo mv "$file" "${file%%.*}_$file" fi done } recurse /path/to/files 
 find . -type f | while read FN; do BFN=$(basename "$FN") NFN=${BFN%.*}_${BFN} echo "$BFN -> $NFN" mv "$FN" "$NFN" done 

我喜欢PERL食谱的重命名脚本。 它可能不是/ bin / sh,但你可以做正则表达式重命名。

/ bin / sh方法是使用sed / cut / awk来更改for循环中的每个文件名。 如果目录很大,你需要依靠xargs。

应该提到mmv工具,这是特别为此做的。

这里描述: http : //tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html

…以及替代品。

我使用prename(基于perl),它包含在各种Linux发行版中。 它适用于正则表达式,所以要把所有的img_x.jpg改成IMAGE_x.jpg

 prename 's/img_/IMAGE_/' img*jpg 

您可以使用-n标志预览更改,而不进行任何实际的更改。

姓名男子入口

 #!/bin/bash # Don't do this like I did: # files=`ls ${1}` for file in *.* do if [ -f $file ]; then newname=${file%%.*}_${file} mv $file $newname fi done 

这一个不会重命名子目录,只有常规的文件。