如何在Linux中使用正则表达式捕获组重命名文件?

4
我想将a_1.0.tgz重命名为b_1.0.tgz,由于1.0可能会更改为任何版本号,我该如何实现呢?
例如,如果不需要保留版本号,可以使用mv a*.tgz b.tgz
3个回答

12

zsh 自带实用程序 zmv,旨在实现这一点。虽然 zmv 不支持正则表达式,但它提供了文件名生成模式(又称 globbing)的捕获组。

首先,您可能需要启用 zmv。这可以通过将以下内容添加到您的 ~/.zshrc 中来完成:

autoload -Uz zmv
您可以像这样使用它:
zmv 'a_(*)' 'b_$1'

这将重命名与 a_* 匹配的任何文件,使得 a_ 被替换为 b_。如果您想更具体,当然可以调整模式:

  • 仅重命名 .tgz 文件:

zmv 'a_(*.tgz)' 'b_$1'
  • 仅重命名扩展名为.tgz的文件,并将其更改为.tar.gz

  • zmv 'a_(*).tgz' 'b_$1.tar.gz'
    
  • 仅重命名 a_1.0.tgz:

  • zmv 'a_(1.0.tgz)' 'b_$1'
    

    为了保险起见,您可以首先使用选项-n运行zmv。这只会打印出可能发生的情况,而不会实际更改任何内容。有关更多信息,请查看man zshcontrib


    2

    我对 zsh 不是很熟悉,所以不知道它是否支持正则表达式,但在这里我认为您实际上并不需要它们。

    您可以使用通配符匹配文件,并使用替换:

    for file in a_[0-9].[0-9].tgz; do 
        echo "$file" "${file/a/b}"
    done
    

    在全局模式中,[0-9] 匹配 0 到 9 之间的任何数字。 ${file/a/b} 将第一个出现的 a 替换为 b
    如果您对结果满意,请将echo更改为mv

    版本号可以是1.1.1这样的形式,不限于两个数字。是否有可能将a后面的所有内容作为一个组,并将此组添加到b之后? - JasmineOT
    你可以在全局模式中匹配任何你想要的内容(例如,a_*.tgz),并使用相同的替换形式 "${file/a/b}" 将字母 a 替换为 b - Tom Fenech

    0

    假设您想要将所有匹配`a*.tgz`的文件中的第一个字符替换为字母 `b` :

    for f in a*.tgz; do
      echo mv "$f" "b${f:1}"
    done
    

    当您确定其已实现想要的功能时,请移除 echo

    $ {f:1} 使用 $ {name:offset} 参数扩展。来自 zshexpn 手册(在OS X上):

    如果偏移量为非负,则如果变量名称是标量,从字符串的第一个字符开始替换内容偏移量个字符,[...]。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接