我有一堆需要重命名的文件。
file1.txt needs to be renamed to file1_file1.txt
file2.avi needs to be renamed to file2_file2.avi
你可以看到我需要原始文件名后面的_。
这些文件很多。
答案 0 :(得分:5)
到目前为止,所有答案都是:
这两个脚本解决了所有这些问题。
#!/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
修复了以前版本中未正确处理路径名的问题。
答案 1 :(得分:4)
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
答案 2 :(得分:4)
对于您的具体情况,您希望使用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
您需要知道通配符匹配并不贪婪。这意味着文件a.b.txt
将变为a_a.b.txt
,而不是a.b_a.b.txt
。
mmv
程序是作为我的CygWin的一部分安装的,但我必须
sudo apt-get install mmv
在我的Ubuntu盒子上让它失效。如果它不在您的标准发行版中,那么您使用的任何包管理器都希望它可用。
如果出于某种原因,您不允许安装它,则必须使用其他答案中显示的其他bash
for
- 循环类型解决方案之一。我更喜欢mmv
我自己的简洁,但你可能没有选择。
答案 3 :(得分:2)
find . -type f | while read FN; do
BFN=$(basename "$FN")
NFN=${BFN%.*}_${BFN}
echo "$BFN -> $NFN"
mv "$FN" "$NFN"
done
答案 4 :(得分:0)
我喜欢PERL cookbook的重命名脚本。它可能不是/ bin / sh,但你可以进行正则表达式重命名。
/ bin / sh方法是使用sed / cut / awk来改变for循环中的每个文件名。如果目录很大,则需要依赖xargs。
答案 5 :(得分:0)
应该提到mmv
工具,这是为此特别制作的。
这里描述:http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html
......以及替代品。
答案 6 :(得分:0)
我使用prename(基于perl),它包含在各种Linux发行版中。它适用于正则表达式,所以要说将所有img_x.jpg改为你要做的IMAGE_x.jpg
prename 's/img_/IMAGE_/' img*jpg
您可以使用-n标志预览更改,而不进行任何实际更改。
答案 7 :(得分:-1)
#!/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
这个不会重命名子目录,只会重命名常规文件。