【问题标题】:Rename files in a tree that have extension included in base name重命名树中具有包含在基本名称中的扩展名的文件
【发布时间】:2019-06-10 20:32:45
【问题描述】:

我在 CentOS 服务器上的一个目录(以及许多子目录)中有一堆文件,这些文件的扩展名意外地粘在了基本名称上,就像这样。

12345jpg

我想将它们全部重命名为

12345.jpg

我已经接近这个命令,但不能完全让重命名正则表达式工作。

find . -type f ! -name "*.*" -exec rename 's/([0-9]{5})(.*)/$1.$2/'

 

更新:使用 sed 代替重命名会更好吗?像这样? (目前也不起作用)

find . -type f ! -name "*.*" -exec sed -i '' s/([0-9]{5})(.*)/1.2/g {} ;

【问题讨论】:

    标签: regex linux centos find rename


    【解决方案1】:

    您需要正确转义您的正则表达式并在替换中使用\1.\2

    s/\([0-9]\{5\}\)\(.*\)/\1.\2/
    

    例如:

    $ echo '12345jpg' | sed 's/\([0-9]\{5\}\)\(.*\)/\1.\2/'
    12345.jpg
    

    【讨论】:

      【解决方案2】:

      我认为rename 实用程序不能处理反向引用。

      这是一个可移植的 posix-only 解决方案:

      find . -type f -name '[0-9][0-9][0-9][0-9][0-9]?*' \
             -not -name '*.*' |while IFS= read file; do
        dir="${file%/*}"
        file="${file#$dir/}"
        B="${file#?????}"
        A="${file%$B}"
        mv -i "$dir/$file" "$dir/$A.$B"
      done
      

      这使用 shell globbing(缺少量词,因此存在冗余)来确保我们只重命名具有预期的五个前导数字,然后至少还有一个字符的文件,同时排除名称中带有点的文件。

      然后它会逐行循环(是的,如果您的文件名中有换行符,这将中断 - 不要那样做!)。我明确清除了$IFS,因此空格不会被解释为字段分隔符。

      在 while 循环中,我按摩文件名。首先,我提取目录名(如果没有,则为./;如果您偏离find . …,请小心),然后更改$file 变量以仅存储文件名。然后我将$B 分配给缺少前五个字符的文件名(find 已经要求是数字),$A 是前五个字符。现在我们可以使用额外的点进行重命名。

      我使用mv -i 作为安全措施。这将在这样做之前以交互方式询问您要覆盖的任何内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-06
        • 1970-01-01
        • 2013-07-05
        • 2014-03-05
        • 1970-01-01
        相关资源
        最近更新 更多