我有一堆需要重新命名的文件。
file1.txt needs to be renamed to file1_file1.txt file2.avi needs to be renamed to file2_file2.avi
正如你所看到的,我需要的是原始文件名。
有很多这些文件。
到目前为止,所有的答案都是:
这两个脚本解决了所有这些问题。
#!/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)
#!/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
这一个不会重命名子目录,只有常规的文件。