重命名文件名,以便按指定的排序顺序显示

Rename the file names so that the appear in a specified sorted order

我有一个文件列表。它们目前按以下顺序出现:

Advance Topics in Graphs _ Lec 11 _ Discrete Mathematics _ Exam-lAN6B0Hvy7E.webm
Basics of Combinatorics _ Lec 12 _ Discrete Mathematics _ Exam-sBg13JNUQQ8.webm
Basics of Graph Theory _ Lec 6 _ Discrete Mathematics _ Exam-JqgdPH-PEIM.webm
Basics of Relations - 2 _ Lec 20 _ Discrete Mathematics _ Exam-CTo9pvl__5M.webm
Basics of Relations _ Lec 19 _ Discrete Mathematics _ Exam-4KTaggHRd54.webm
Basics of Sets _ Lec 18 _ Discrete Mathematics _ Exam-LE-Gt_PUdws.webm

我想重命名文件,使文件名具有以下模式(为清楚起见,使用正则表达式表示)Lec\s[0-9]?[0-9]?出现在文件名中间,出现在文件名开头。(这是排序顺序)。

最终结果将如下所示:

Lec 6 Basics of Graph Theory _  _ Discrete Mathematics _ Exam-JqgdPH-PEIM.webm
Lec 11 Advance Topics in Graphs _  _ Discrete Mathematics _ Exam-lAN6B0Hvy7E.webm
Lec 12 Basics of Combinatorics _  _ Discrete Mathematics _ Exam-sBg13JNUQQ8.webm
Lec 18 Basics of Sets _  _ Discrete Mathematics _ Exam-LE-Gt_PUdws.webm
Lec 19 Basics of Relations _  _ Discrete Mathematics _ Exam-4KTaggHRd54.webm
Lec 20 Basics of Relations - 2 _  _ Discrete Mathematics _ Exam-CTo9pvl__5M.webm

注意:这需要 gawk 因为 gensub

ls | awk '{a=gensub(/^(.*) (Lec [0-9]+) (.*)$/, "\2 \1\3","1",[=10=]);printf "mv \"%s\" \"%s\"\n",[=10=], a}' |  bash

每当我遇到这样的问题时,我倾向于编写一个一次性脚本来完成 Python 中的工作,尽管您可以用任何选择的语言替换它(即 Perl,bash+awk,..)

这主要是为了确保您在真正进行重命名之前知道结果会是什么,这可能是一个破坏性操作(丢弃标识符,将所有输入文件重命名为具有相同的名称,因此只有最后一个存活下来..)!

import os
import re

def mapper(s):
    # adjust to taste, this just swaps the middle to the front
    prefix, index, postfix = re.match(r"^(.*) (?:Lec) (\d+) (.*)$", s).groups()
    return f"Lec {int(index):02} {prefix} {postfix}"  # pad index 2->02, etc.

mapping = {}  # start a new dictionary to store src->dest maps
for name_file in os.listdir():
    try:
        mapping[name_file] = mapper(name_file)
    except AttributeError:  # failed to match
        print(f"failed to match for {name_file}")

# display the change on separate lines
for src, dest in mapping.items():
    print(f"{src} -> {dest}")

# [return] or ^C to quit
input("continue?..")

# perform renames
for src, dest in mapping.items():
    os.rename(src, dest)

鉴于:

ls -1 *.webm
Advance Topics in Graphs _ Lec 11 _ Discrete Mathematics _ Exam-lAN6B0Hvy7E.webm
Basics of Combinatorics _ Lec 12 _ Discrete Mathematics _ Exam-sBg13JNUQQ8.webm
Basics of Graph Theory _ Lec 6 _ Discrete Mathematics _ Exam-JqgdPH-PEIM.webm
Basics of Relations - 2 _ Lec 20 _ Discrete Mathematics _ Exam-CTo9pvl__5M.webm
Basics of Relations _ Lec 19 _ Discrete Mathematics _ Exam-4KTaggHRd54.webm
Basics of Sets _ Lec 18 _ Discrete Mathematics _ Exam-LE-Gt_PUdws.webm 

我会在 Ruby 中做一点衬垫:

ruby -e 'Dir.glob("*.webm"){
        |fn| File.rename(fn, fn.sub(/^([^_]*)_ ([^_]+? )_/,"\2\1_ _"))}'

然后:

ls -1 *.webm
Lec 11 Advance Topics in Graphs _ _ Discrete Mathematics _ Exam-lAN6B0Hvy7E.webm
Lec 12 Basics of Combinatorics _ _ Discrete Mathematics _ Exam-sBg13JNUQQ8.webm
Lec 18 Basics of Sets _ _ Discrete Mathematics _ Exam-LE-Gt_PUdws.webm
Lec 19 Basics of Relations _ _ Discrete Mathematics _ Exam-4KTaggHRd54.webm
Lec 20 Basics of Relations - 2 _ _ Discrete Mathematics _ Exam-CTo9pvl__5M.webm
Lec 6 Basics of Graph Theory _ _ Discrete Mathematics _ Exam-JqgdPH-PEIM.webm

但是请注意,如果新名称与之前生成的名称相同,此(以及此处的所有其他解决方案)将覆盖文件...