linux – 更好的方式根据多种模式重命名文件

前端之家收集整理的这篇文章主要介绍了linux – 更好的方式根据多种模式重命名文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
很多我下载的文件在他们的文件名中有垃圾邮件/垃圾邮件,例如

[www.crap.com] file.name.ext

www.crap.com – file.name.ext

我想出了两种处理方法,但是他们似乎很笨重:

参数扩展:

if [[ ${base_name} != ${base_name//\[+([^\]])\]} ]]
then
    mv -v "${dir_name}/${base_name}" "${dir_name}/${base_name//\[+([^\]])\]}" &&
        base_name="${base_name//\[+([^\]])\]}"
fi

if [[ ${base_name} != ${base_name//www.*.com - /} ]]
then
    mv -v "${dir_name}/${base_name}" "${dir_name}/${base_name//www.*.com - /}" &&
        base_name="${base_name//www.*.com - /}"
fi

# more of these type of statements; one for each type of frequently-encountered pattern

然后用echo / sed:

tmp=`echo "${base_name}" | sed -e 's/\[[^][]*\]//g' | sed -e 's/\s-\s//g'`
mv "${base_name}" "{tmp}"

我觉得参数扩展是更糟糕的两个,但我喜欢它,因为我可以保留相同的变量分配给文件进行进一步处理后重命名(上述代码用于每个文件的脚本中使用文件下载完成后).

所以无论如何,我希望有一个更好/更干净的方式做上述,比我自己更有知识的人可以告诉我,最好是允许我轻松地将旧/原始变量重新分配到新/重命名文件.

谢谢

解决方法

两个答案:使用 perl重命名或使用纯 bash

因为有些人不喜欢perl,我写了我的bash唯一版本

使用rename命令重命名文件.

介绍

是的,这是重命名命令的典型工作,它是专为以下设计:

man rename | sed -ne '/example/,/^[^ ]/p'
   For example,to rename all files matching "*.bak" to strip the
   extension,you might say

           rename 's/\.bak$//' *.bak

   To translate uppercase names to lower,you'd use

           rename 'y/A-Z/a-z/' *

更加面向样品

只需放下所有空格和方括号:

rename 's/[ \[\]]*//g;' *.ext

通过编号从1重命名所有.jpg

rename 's/^.*$/sprintf "IMG_%05d.JPG",++$./e' *.jpg

演示:

touch {a..e}.jpg
ls -ltr
total 0
-rw-r--r-- 1 user user 0 sep  6 16:35 e.jpg
-rw-r--r-- 1 user user 0 sep  6 16:35 d.jpg
-rw-r--r-- 1 user user 0 sep  6 16:35 c.jpg
-rw-r--r-- 1 user user 0 sep  6 16:35 b.jpg
-rw-r--r-- 1 user user 0 sep  6 16:35 a.jpg
rename 's/^.*$/sprintf "IMG_%05d.JPG",++$./e' *.jpg
ls -ltr
total 0
-rw-r--r-- 1 user user 0 sep  6 16:35 IMG_00005.JPG
-rw-r--r-- 1 user user 0 sep  6 16:35 IMG_00004.JPG
-rw-r--r-- 1 user user 0 sep  6 16:35 IMG_00003.JPG
-rw-r--r-- 1 user user 0 sep  6 16:35 IMG_00002.JPG
-rw-r--r-- 1 user user 0 sep  6 16:35 IMG_00001.JPG

完整的语法用于匹配SO问题,以安全的方式

使用重命名实用程序有一个强大而安全的方式:

由于这是perl常用工具,我们必须使用perl语法:

rename 'my $o=$_;
        s/[ \[\]]+/-/g;
        s/-+/-/g;
        s/^-//g;
        s/-\(\..*\|\)$/$1/g;
        s/(.*[^\d])(|-(\d+))(\.[a-z0-9]{2,6})$/
                my $i=$3;
                $i=0 unless $i;
                sprintf("%s-%d%s",$1,$i+1,$4)
            /eg while
               $o ne $_  &&
               -f $_;
    ' *

测试规则:

touch '[ www.crap.com ] file.name.ext' 'www.crap.com - file.name.ext'
ls -1
[ www.crap.com ] file.name.ext
www.crap.com - file.name.ext
rename 'my $o=$_; ...
    ...
    ...' *
ls -1
www.crap.com-file.name-1.ext
www.crap.com-file.name.ext

touch '[ www.crap.com ] file.name.ext' 'www.crap.com - file.name.ext'
ls -1
www.crap.com-file.name-1.ext
[ www.crap.com ] file.name.ext
www.crap.com - file.name.ext
www.crap.com-file.name.ext
rename 'my $o=$_; ...
    ...
    ...' *
ls -1
www.crap.com-file.name-1.ext
www.crap.com-file.name-2.ext
www.crap.com-file.name-3.ext
www.crap.com-file.name.ext

… 等等…

…它是安全的,而你不使用-f标志重命名命令:文件将不会被覆盖,如果出现问题,您将收到一条错误消息.

通过使用bash和所谓的bashisms重命名文件

我更喜欢通过使用专用的实用程序,但这甚至可以通过使用纯bash(也就是没有任何叉子)

没有使用任何其他二进制文件比bash(没有sed,awk,tr或其他):

#!/bin/bash

for file;do
    newname=${file//[ \]\[]/.}
    while [ "$newname" != "${newname#.}" ] ;do
        newname=${newname#.}
      done
    while [ "$newname" != "${newname//[.-][.-]/.}" ] ;do
        newname=${newname//[.-][.-]/-};done
    if [ "$file" != "$newname" ] ;then
        if [ -f $newname ] ;then
            ext=${newname##*.}
            basename=${newname%.$ext}
            partname=${basename%%-[0-9]}
            count=${basename#${partname}-}
            [ "$partname" = "$count" ] && count=0
            while printf -v newname "%s-%d.%s" $partname $[++count] $ext &&
                  [ -f "$newname" ] ;do
              :;done
          fi
        mv  "$file" $newname
      fi
  done

要以文件作为参数运行,示例:

/path/to/my/script.sh \[*

>用点替换空格和方括号>只用一个 – 替换.-,– .,– 或..的顺序.>测试文件名是否不同,没有任何关系.>测试一个文件是否存在newname …>分割文件名,计数器和扩展名,用于创建索引的新名称>如果一个文件存在newname,则循环> Finaly重命名文件.

猜你在找的Linux相关文章