我有一个目录,里面有随机名称的文件。我想将文件重命名为 file1、file2 等等。按字典顺序排列较小的文件名应该用较小的数字编号。我该怎么做?
答案1
一个简单的 bash 脚本就可以完成。
#!/usr/bin/env bash
count=0
for i in *; do
mv "${i}" file${count}.`echo "${i}" | awk -F. '{print $2}'`
((++count))
done
为了帮助逐行解释:
- 执行的 bash shell 的位置,由您的环境变量决定。
- 将变量“count”设置为 0
- 创建一个 for 循环,迭代命令的输出
ls
(默认按字母顺序排序)。 - 将文件“i”(循环中的当前文件)移动(即重命名)到
file#.ext
。“#”是“count”中的当前数字,“.”后面的内容是获取当前文件扩展名的快捷方式(因此这可以在包含各种文件扩展名的文件夹中使用)。 - 增加计数器变量
循环,循环,循环
- 完毕!
笔记:
这会在您执行它的任何目录中执行。因此,作为脚本,您需要添加命令行参数。相反,我会打开一个终端,导航到要执行此操作的目录,然后执行以下操作(准确):
for i in *; do mv "${i}" "file${count}".`echo "${i}" | awk -F. '{print $2}'`; ((++count)); done
这是假设您只有文件名,例如“file.txt”,而不是“this.is.a.file.txt”
答案2
你可以使用这个python脚本:
#!/usr/bin/python
import os
#enter the path to the folder: relative or absolute
direc = raw_input('Enter the path to directory: ')
os.chdir(os.path.join(os.getcwd(),direc))
files = os.listdir('.')
def func(x):
return map(str.lower,os.path.splitext(x))
files.sort(key = func)
for i,x in enumerate(files, 1):
name, ext = os.path.splitext(x)
os.rename(x, 'file{}{}'.format(i,ext))
答案3
A狂欢可能性(类似于 nerdwaller 的解决方案,但没有子 shell 和 forkawk):
#!/usr/bin/bash
shopt -s nullglob
count=0
for i in *; do
mv -nv -- "$i" "file$((++count))"
done
开关mv
:
-n
表示无覆盖:不会覆盖其他现有文件。如果您确实想覆盖文件,请将其删除(可能不可用,具体取决于您的 版本mv
),-v
详细:告诉它正在做什么。高度可选(但我喜欢在终端上显示这些行以给我的同事留下深刻印象),--
选项结尾:如果没有这个,如果文件名以连字符开头,就会造成混淆,mv
因为它会尝试将其解释为选项。可能不可用,具体取决于您的 版本mv
。如果可用,请使用它!
我还使用了 shell 可选行为nullglob
,这样如果没有文件,那么您将不会收到任何错误(循环将不会执行,因为*
在这种情况下会扩展为无)。
如果你也需要处理扩展(如 nerdwaller 的版本),你不需要awk,这一切都可以在狂欢:
#!/usr/bin/bash
shopt -s nullglob
count=0
for i in *; do
mv -nv -- "$i" "file$((++count)).${i##*.}"
done
请注意,编号不会有任何前导零,因此您将获得名为如下的文件:
file1
file2
...
file10
file11
...
这可能会打乱列表中文件的顺序。如果您还需要前导零:
#!/usr/bin/bash
shopt -s nullglob
files=( * )
lz=0
for ((n=${#files[@]};n;n/=10)); do ((++lz)); done
count=0
for i in "${files[@]}"; do
printf -v n "%0${lz}d" $((++count))
mv -nv -- "$i" "file$n"
done
如果你想保留原始文件的扩展名,请将以下行替换
mv -nv -- "$i" "file$n"
和
mv -nv -- "$i" "file$n.${i##*.}"
注意事项。
- 因为这使用狂欢通配符,如果你的目录中有大量文件,它可能会非常慢(通配符可能需要一些时间)。
- 这将重命名所有内容,包括目录,但不包括隐藏文件。
治愈方法。
- 如果文件数量巨大,我没有任何关于速度的解决方案狂欢。
- 如果您需要从此重命名过程中丢弃目录并仅重命名文件,请在语句
[[ -f $i ]] || continue
后添加for i in *; do
。 - 如果您还需要重命名隐藏文件,请
shopt -s dotglob
在shopt -s nullglob
语句后添加。
如果你读到这里,我想你就能从我给你的例子中制作出符合你自己需要的东西,希望使用好的狂欢练习(前提是你选择使用以下方法解决问题狂欢当然)。
答案4
当我还是学生并且正在学习 Linux Shell 脚本时,我想实现相同的功能。然后我创建了下面的脚本。看一看。 https://github.com/rushyang/GTU-OS-Bash-Scripts/blob/master/Working/System%20Scripts/final_rename_updated.sh