在 Linux 中,如何按照某种模式重命名目录中的多个文件?

在 Linux 中,如何按照某种模式重命名目录中的多个文件?

我有一个目录,里面有随机名称的文件。我想将文件重命名为 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

为了帮助逐行解释:

  1. 执行的 bash shell 的位置,由您的环境变量决定。
  2. 将变量“count”设置为 0
  3. 创建一个 for 循环,迭代命令的输出ls(默认按字母顺序排序)。
  4. 将文件“i”(循环中的当前文件)移动(即重命名)到file#.ext。“#”是“count”中的当前数字,“.”后面的内容是获取当前文件扩展名的快捷方式(因此这可以在包含各种文件扩展名的文件夹中使用)。
  5. 增加计数器变量

循环,循环,循环

  1. 完毕!

笔记

  1. 这会在您执行它的任何目录中执行。因此,作为脚本,您需要添加命令行参数。相反,我会打开一个终端,导航到要执行此操作的目录,然后执行以下操作(准确):

    for i in *; do mv "${i}" "file${count}".`echo "${i}" | 
      awk -F. '{print $2}'`; ((++count)); done
    
  2. 这是假设您只有文件名,例如“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 和 fork):

#!/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 的版本),你不需要,这一切都可以在

#!/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 dotglobshopt -s nullglob语句后添加。

如果你读到这里,我想你就能从我给你的例子中制作出符合你自己需要的东西,希望使用好的练习(前提是你选择使用以下方法解决问题当然)。

答案4

当我还是学生并且正在学习 Linux Shell 脚本时,我想实现相同的功能。然后我创建了下面的脚本。看一看。 https://github.com/rushyang/GTU-OS-Bash-Scripts/blob/master/Working/System%20Scripts/final_rename_updated.sh

相关内容