bash bash脚本重命名目录中的所有文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1956144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash script to rename all files in a directory?
提问by gpow
i have bunch of files that needs to be renamed.
我有一堆需要重命名的文件。
file1.txt needs to be renamed to file1_file1.txt
file2.avi needs to be renamed to file2_file2.avi
as you can see i need the _ folowed by the original file name.
如您所见,我需要原始文件名后面的 _。
there are lot of these files.
有很多这样的文件。
回答by SiegeX
So far all the answers given either:
到目前为止,所有答案都给出了:
- Require some non-portable tool
- Break horribly with filenames containing spaces or newlines
- Is not recursive, i.e. does not descend into sub-directories
- 需要一些非便携式工具
- 用包含空格或换行符的文件名可怕地打破
- 不是递归的,即不下降到子目录
These two scripts solve all of those problems.
这两个脚本解决了所有这些问题。
Bash 2.X/3.X
重击 2.X/3.X
#!/bin/bash
while IFS= read -r -d $'#!/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
' file; do
dirname="${file%/*}/"
basename="${file:${#dirname}}"
echo mv "$file" "$dirname${basename%.*}_$basename"
done < <(find . -type f -print0)
Bash 4.X
重击 4.X
for file in file*.*
do
[ -f "$file" ] && echo mv "$file" "${file%%.*}_$file"
done
Be sure to remove the echofrom whichever script you choose once you are satisfied with it's output and run it again
echo一旦您对它的输出感到满意并再次运行它,请务必从您选择的任何脚本中删除
Edit
编辑
Fixed problem in previous version that did not properly handle path names.
修复了以前版本中无法正确处理路径名的问题。
回答by ghostdog74
recurse() {
for file in ""/*;do
if [ -d "$file" ];then
recurse "$file"
else
# check for relevant files
# echo mv "$file" "${file%%.*}_$file"
fi
done
}
recurse /path/to/files
Idea for recursion
递归的想法
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
回答by paxdiablo
For your specific case, you want to use mmvas follows:
对于您的特定情况,您希望使用mmv如下:
sudo apt-get install mmv
You need to be aware that the wildcard matching is not greedy. That means that the file a.b.txtwill be turned into a_a.b.txt, not a.b_a.b.txt.
您需要注意通配符匹配不是贪婪的。这意味着文件a.b.txt将变成a_a.b.txt,而不是a.b_a.b.txt.
The mmvprogram was installed as part of my CygWin but I had to
该mmv程序是作为 CygWin 的一部分安装的,但我必须
find . -type f | while read FN; do
BFN=$(basename "$FN")
NFN=${BFN%.*}_${BFN}
echo "$BFN -> $NFN"
mv "$FN" "$NFN"
done
on my Ubuntu box to get it down. If it's not in you standard distribution, whatever package manager you're using will hopefully have it available.
在我的 Ubuntu 盒子上把它拿下来。如果它不在您的标准发行版中,那么您使用的任何包管理器都希望可以使用它。
If, for some reason, you're not permitted to install it, you'll have to use one of the other bashfor-loop-type solutions shown in the other answers. I prefer the terseness of mmvmyself but you may not have the option.
如果由于某种原因不允许您安装它,则必须使用bashfor其他答案中显示的其他-loop 类型解决方案之一。我更喜欢mmv自己的简洁,但你可能没有选择。
回答by Rob Curtis
prename 's/img_/IMAGE_/' img*jpg
回答by Carl Smotricz
One should mention the mmvtool, which is especially made for this.
应该提到这个mmv工具,它是专门为此而制作的。
It's described here: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html
它在这里描述:http: //tldp.org/LDP/GNU-Linux-Tools-Summary/html/mass-rename.html
...along with alternatives.
...以及替代方案。
回答by JAL
I use prename (perl based), which is included in various linux distributions. It works with regular expressions, so to say change all img_x.jpg to IMAGE_x.jpg you'd do
我使用 prename(基于 perl),它包含在各种 linux 发行版中。它适用于正则表达式,所以说将所有 img_x.jpg 更改为 IMAGE_x.jpg 你会这样做
#!/bin/bash
# Don't do this like I did:
# files=`ls `
for file in *.*
do
if [ -f $file ];
then
newname=${file%%.*}_${file}
mv $file $newname
fi
done
You can use the -n flag to preview changes without making any actual changes.
您可以使用 -n 标志预览更改而不进行任何实际更改。
回答by Epsilon Prime
I like the PERL cookbook's rename script for this. It may not be /bin/sh but you can do regular expression-like renames.
我喜欢 PERL 食谱的重命名脚本。它可能不是 /bin/sh 但您可以进行类似正则表达式的重命名。
The /bin/sh method would be to use sed/cut/awk to alter each filename inside a for loop. If the directory is large you'd need to rely on xargs.
/bin/sh 方法是使用 sed/cut/awk 来改变 for 循环中的每个文件名。如果目录很大,则需要依赖 xargs。
回答by James Morris
This one won't rename sub directories, only regular files.
这个不会重命名子目录,只会重命名常规文件。

