使用 find 和 execdir 标志补零文件名

使用 find 和 execdir 标志补零文件名

我正在使用 smplayer,它不会按自然顺序对文件进行排序,例如播放后1*.sth它会跳转到11*.sth而不是2*.sth.但正如我所检查的,如果我将文件名更改为零,那么该播放器将以正确的顺序对文件进行排序。(*我的意思是任何字符,如破折号、空格、点等)现在我正在尝试编写一行(如果可能的话)一次性可执行代码,用于检查所有视频和 srt 文件并用零填充。我有这个代码来查找我需要重命名的所有文件:

~~~~~~find . -type f -regex "[^0].*\.\(mp4\|srt\)"
find . -type f -name '[1-9]*.mp4' -o -name '[1-9]*.srt'

find . '(' -name '[1-9]*.mp4' -o -name '[1-9]*.srt' ')' -type f

我知道find有一个execdir标志将执行命令,并且指定的命令是从包含匹配文件的子目录运行的。此信息很有用,因为如果我想从目录树的最顶层节点运行结果命令,那么我不需要担心文件所在的位置。现在的问题是我不知道如何使用 bash 脚本对文件名进行零填充并使用此函数作为方法-execdir标志的命令find

这段代码将

awk '{ split($0, arr, "/"); print arr[2] }'

我有一个适合我的 python 脚本,但我正在寻找一个单行 bash 脚本来完成这项工作。

import subprocess
from pathlib import Path

cmd = r'find ./ -type f -regex "[^0].*\.\(mp4\|srt\)"'
exc = subprocess.check_output(cmd, shell=True)

pathes = list(map(bytes.decode, exc.splitlines()))
files = list(map(Path, pathes))

for file in files:
    if file.name[0].isdigit() and file.name[0] != "0":
        num = ""
        for char in file.name:
            if not char.isdigit():
                break
            num += char
        file.rename(file.with_name(file.name.replace(num, num.rjust(3, "0"))))

在此输入图像描述

答案1

mp4要将零填充到长度 4,例如所有文件开头的数字srt,请使用zsh

autoload -Uz zmv
zmv '(**/)(<->)(*.(mp4|srt))(#q.)' '$1${(l[4][0])2}$3'

或者如果您有以下rename命令:perlFile::Rename

find . '(' -name '*.mp4' -o -name '*.srt' ')' -type f -print0 |
  rename -0d 's/^\d+/sprintf "%04d", $&/e'

请注意-regex,在find支持它的实现中,它与整个路径匹配,而不仅仅是文件名,并且默认情况下是锚定的。

find . -type f -regex "[^0].*\.\(mp4\|srt\)"

所有路径都以 开头./。例如,它可能与该正则表达式匹配,因为它以( )./dir/01.mp4以外的字符开头,后跟 0 个或多个字符,后跟。0..mp4

你的意思可能是这样的:

find . '(' -name '[123456789]*.mp4' -o -name '[123456789]*.srt' ')' -type f

查找常规文件姓名以 0 以外的数字开头。

或者:

find -E . -regex '.*/[0123456789]{1,3}([^0123456789/][^/]*)?\.(mp4|srt)' -type f

适用于名称以长度小于 4 的数字序列开头的常规文件。

如果您find是 GNU find,请替换-E .. -regextype posix-extended.与 BSD 上的实现-E等效。find

相关内容