AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 690767
Accepted
Henke
Henke
Asked: 2022-02-16 06:07:03 +0800 CST2022-02-16 06:07:03 +0800 CST 2022-02-16 06:07:03 +0800 CST

如何批量重命名包含空格的文件/目录?

  • 772

如何通过替换文件/目录名称中的片段来批量重命名许多文件和/或f o o目录b a r?

对于每种建议的方法,最好回答以下问题。

  • 是否可以在进行实际重命名之前预览命令的结果?如何?
  • 该方法是否仅适用于前缀,仅适用于后缀,还是不适用?
  • 重命名是只影响目录、只影响文件,还是同时影响目录和文件?
  • 子目录中的文件/目录也会被重命名吗?

替换前缀,示例

为了使任务更具体一点,假设文件
o l d prefix file 1.c
o l d prefix file 1.h
o l d prefix file 2.c
o l d prefix file 2.h
应该重命名为
n e w prefix file 1.c
n e w prefix file 1.h
n e w prefix file 2.c
n e w prefix file 2.h

还假设在同一目录中有(子)目录名为
o l d prefix, dir 1 _
o l d prefix, dir 2 _

这些目录也会被重命名吗?

你能调整你的方法来只重命名目录(而不是文件)吗?
或者只重命名文件(而不是目录)?

替换后缀

还可以考虑重命名文件中的后缀,以便将
file 1, o l d suffixandfile 2, o l d suffix分别重命名为
file 1, n e w suffixand file 2, n e w suffix。

对于目录也是如此。
dir 1., o l d suffix将和分别重命名dir 2., o l d suffix为
dir 1., n e w suffix和dir 2., n e w suffix。

推荐的方法?

你会推荐什么重命名方法?

笔记

请注意,向名称添加前缀或后缀只是更通用替换前缀或后缀的一种特殊情况,即原始前缀或后缀恰好是空字符串的情况。类似地,去除前缀或后缀的情况也是替换前缀或后缀的一种特殊情况,即新的前缀或后缀为空字符串的情况。

更多需要考虑的问题

我知道在重命名文件时还需要考虑其他更高级的问题,例如添加或删除日期或序列号和/或以下参考文献中最后五个问题中的主题。

我邀请您提出有关重命名文件/目录(或符号链接)的任何问题,并在您的答案中构建一个合适的示例。

写答案时,不要觉得你必须回答这里提出的所有案例!如果您愿意,请
随意只关注一个特定案例(上述案例之一,或您选择的其他案例)。

参考

  • 让我们编制一份规范的问答列表
  • 批量重命名文件
  • 批量重命名,更改前缀
  • 重命名本地文件夹中的文件,添加前缀或后缀
  • 重命名一堆文件但保留数字部分
  • 根据文本文件重命名文件列表
  • 删除文件名开头和结尾的字符模式
  • 重命名多个目录递减序列号?
  • 通过将今天的日期替换为昨天的日期来重命名文件
bash shell
  • 1 1 个回答
  • 562 Views

1 个回答

  • Voted
  1. Best Answer
    Henke
    2022-02-16T06:07:03+08:002022-02-16T06:07:03+08:00

    0. 针对通用解决方案1

    为了方便我未来的自己和其他读者,我将专注于通用解决方案。

    为简单起见,我假设在任何文件/目录名称 中都没有引号——没有双引号 ( ") 和单引号 ( )。2'

    作为第一个示例,我将展示如何使用模式重命名文件
    o l d prefix file *.*to
    n e w prefix file *.*,
    从而即使文件名中有空格也可以重命名前缀。

    我也对重命名目录感兴趣,因此会考虑将目录
    o l d prefix, dir 1 _和分别重命名o l d prefix, dir 2 _为
    n e w prefix, dir 1 _和n e w prefix, dir 2 _。

    其次,我将展示如何替换后缀。例如,文件
    file 1, o l d suffix和file 2, o l d suffix分别重命名为
    file 1, n e w suffix和file 2, n e w suffix。

    同样,我想看看这如何影响(或不影响)目录。
    因此,我还将检查目录
    dir 1., o l d suffix和是否dir 2., o l d suffix分别重命名为
    dir 1., n e w suffix和dir 2., n e w suffix。 3

    所有上述文件和目录都可以在 zip 文件中找到:http:
    //user.it.uu.se/~hesc0353/Files-&-dirs-SEunix-A690768.zip。 4

    笔记。
    以下echo解决方案中出现 表示不会发生重命名。这是一种在您决定进行重命名之前预览
    重命名 的既定技术。 一旦预览看起来正常,只需删除并再次运行命令以执行实际重命名。 5
    echo

    1. 使用 for 循环的通用解决方案

    重命名前缀意味着替换o l d prefix为n e w prefix: 6

    for f in "o l d prefix"*; do\
     echo mv "$f" "n e w prefix""${f#o l d prefix}"; done
    

    我选择搜索以 . 开头的文件o l d pref。

    要重命名后缀,请尝试:

    for f in *"l d suffix"; do\
     echo mv "$f" "${f%o l d suffix}""n e w suffix"; done
    

    重命名是只影响目录、只影响文件,还是同时影响目录和文件?

    – 此方法更改文件和目录的名称。
    如果这不是您想要的,请尝试find ... -type ... -exec 下一节中的方法。

    子目录中的文件/目录也会被重命名吗?

    – 不会。使用上述命令之一作为模板不会影响任何子目录中的文件/目录。如果你想这样做,你将不得不有目的地对方法进行相当多的调整。
    例如,请参阅此答案中的第一个解决方案。

    2.使用的通用解决方案find ... -exec mv

    下面的find ... -exec mv方法使您可以选择仅重命名文件或仅重命名目录-通过-type标志。它也可以被调整以控制命令应该在子目录树中搜索文件或目录的深度——通过 -maxdepth标志。

    重命名前缀

    以下命令替换o l d prefix为n e w prefix,但 仅适用于目录。每个文件都可以在单独的子 shell 中重命名,但通过在内部有一个 for 循环(并用而不是-exec关闭),命令运行效率更高:-execsh {} +{} \;

    find . -maxdepth 1 -type d -name "o l d pr*" -exec sh -c\
     'for n; do echo mv "${n#./}" "n e w pre${n#./o l d pre}"; done' sh {} +
    

    如果您只想重命名文件,只需使用-type f而不是 -type d(容易记住:f用于文件,d用于目录)。

    重命名后缀

    同样,这里是如何替换大量文件中的后缀:

    find . -maxdepth 1 -type f -name "*d suffix" -exec sh -c\
     'for n; do echo mv "$n" "${n%o l d suffix}n e w suffix"; done' sh {} +
    

    解释

    • find .在当前目录及其子目录中搜索。
    • -maxdepth 1不要在任何子目录中搜索。
    • -type f仅查找文件(排除目录)。
    • -name "*d suffix"仅搜索以 . 结尾的文件d suffix。
    • -exec sh -c '...'在子 shell 中执行,允许命令替换,$(...).
    • -exec sh -c 'for n; do mv ...' sh {} +比做
      -exec sh -c 'mv ...' {} \;同样事情的效率更高。 7
    • {}持有任何find发现。
    • echo输出命令的结果——当你对结果满意时,
      删除echo并再次运行命令。
    • mv "sou rce" "dest in"执行实际的重命名,用新名称
      替换旧名称。sou rcedest in
    • %请参阅POSIX shell 模式过滤。
    • done结束 for 循环。
    • sh {} +如前所述,sh {} +关闭-exec sh -c 子句。

    重命名文件和目录

    要一次性重命名文件和目录,只需省略-type:

    find . -maxdepth 1 -name "o l d pr*" -exec sh -c\
     'for n; do echo mv "${n#./}" "n e w pre${n#./o l d pre}"; done' sh {} +
    

    子目录中的文件/目录也会被重命名吗?

    该-maxdepth 1子句确保子目录树中的任何文件/目录都不会受到影响。
    如果您故意要为所有 子目录中的所有文件重命名后缀,这里有一个示例:

    find . -type f -name "*d suffix" -exec sh -c\
     'for n; do echo mv "$n" "${n%o l d suffix}n e w suffix"; done' sh {} +
    

    一句警告。
    此方法不适用于在一个命令中重命名许多不同子目录中的前缀。

    3.使用Perl重命名的解决方案

    本节专门针对那些 在您的系统上安装了由 Larry Wall 重命名的 Perl (或知道如何安装它)的人。 8

    rename我喜欢将Perl-script 重命名为的谨慎做法,prename以避免将其与 Linux rename混淆。

    该方法是否仅适用于前缀,仅适用于后缀,还是不适用?

    您无需担心是重命名前缀还是后缀,这一事实使 Perl 重命名易于使用。

    例如,要替换o l d prefix为n e w prefix,请执行以下操作:

    prename -n 's/o l d prefix/n e w prefix/' ./"o l d p"*
    

    -n标志产生预览的地方。
    一旦结果是您想要的,只需删除-n标志并再次运行命令。

    重命名是只影响目录、只影响文件,还是同时影响目录和文件?

    与第 1 节的 for-loop 方法一样,运行prename将重命名目录和文件。

    if -f但是,您可以通过在重命名字符串的末尾 添加来选择仅重命名文件(不包括目录) ,如下所示: 9

    prename -n 's/o l d prefix/n e w prefix/ if -f' ./"o l d p"*
    

    如果您只想重命名目录(排除文件),请使用 if !-f:

    prename -n 's/o l d prefix/n e w prefix/ if !-f' ./"o l d p"*
    

    子目录中的文件/目录也会被重命名吗?

    我发现 - 当使用正斜杠 ( /) 作为分隔符时 - Perl rename 将仅重命名当前工作目录中的文件/目录,而不是任何子目录中的文件/目录。
    如果您使用其他字符作为分隔符,您实际上可以prename用来重命名子目录树中的文件/目录。这个答案
    的第二个解决方案是这种相当非正统的做法的一个例子。

    更正常的做法是find ... -execdir与 prename.
    对于这样的示例,请参阅 此答案。

    4.重命名文件或目录的其他好方法

    如果您不喜欢上述任何方法,请考虑使用 sedor awk(可能与 结合使用xargs)。

    参考

    • 如何在 Windows 上安装 MSYS2
    • 适用于 Linux 的 Windows 子系统 (WSL)
    • 文件名中禁止使用 ASCII 字符
    • POSIX shell 模式过滤
    • 参数扩展
    • 使用 Bash 重命名文件,删除前缀和后缀
    • 在最深层次重命名许多目录
    • 内部的 for 循环find ... -exec是可选的,但更有效
    • 包含此答案中使用的文件和目录的 Zip 文件
    • 如何终止由-exec
    • Perl rename.pl by Larry Wall
    • Linux 重命名的手册页
    • 使用标志-n预览结果prename
    • 使用-f, 以便只重命名常规文件(而不是目录)
    • [使用深度优先搜索 Perl 重命名文件和目录] https://unix.stackexchange.com/a/366786)
    • sed
    • awk
    • xargs

    1在测试这个答案中提供的命令/解决方案时,我既没有使用过正版Linux,也没有使用正版Unix,而是Windows 10上的MSYS2,可以描述为在Microsoft Windows上运行的模拟arch-Linux。当然,对于像我这样的 Windows 用户来说,一个可行的替代方案是使用 Windows Subsystem for Linux (WSL)。
    我使用 MSYS2 是因为我觉得它方便易用。

    2如果有疑问,在考虑任何重命名之前,请检查
    命令的结果ls *\"*和ls *\'*.
    或者更好的是:find . -name '*"*'和find . -name "*'*"。
    我认为,在文件/目录名称中使用引号肯定是自找麻烦。
    此答案列出了文件/目录名称中禁止使用的字符。
    – 对于 Linux/Unix,只有一个禁止字符:正斜杠 ( /)。

    3我的目标不是一次性更改前缀和后缀的解决方案,如 Renaming files with Bash, remove prefix and suffix问题中所要求的那样。(如果您需要同时重命名前缀和后缀,我建议在一个命令中替换其中一个,然后在另一个命令中替换另一个。)

    4我鼓励读者下载 zip 文件并将其解压缩到某个(空)目录,然后尝试我在此答案中提供的所有命令。

    5对于包含空格的文件和目录,预览可能看起来不正确,因为它缺少周围的双引号 ( ")。删除echo仍然会使命令正确运行。
    (不要太从字面上理解预览!)

    6我使用反斜杠 ( \) 对长命令进行换行,这样读者就无需水平滚动。当您自己构建一个具体示例时,我建议删除反斜杠并将整个命令写在一行中。

    7要了解更多关于 和 之间的区别{} +, {} \;请参阅例如 如何终止由-exec(及其引用)调用的 shell 命令。

    8尝试在您的终端中 输入rename或(然后点击)。如果安装了 Perl rename,预计会看到 或类似的东西 - 其中包含该单词。 如果未安装,预计会看到类似 . 您可以尝试的另一件事是.prenameEnterUsage: rename [-v] [-n] [-f] perlexpr [filenames]perlexpr
    bash: prename: command not found
    which prename

    9 该评论说该 if -f子句还将重命名符号链接。如果不重命名符号链接,
    它建议使用。if (-f && ! -l)

    • 3

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • 如何将带有〜的路径保存到变量中?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve