基于多模式更好的方法来重命名文件 [英] Better way to rename files based on multiple patterns

查看:148
本文介绍了基于多模式更好的方法来重命名文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很多的文件我下载都在其文件名废话/垃圾邮件,例如。

a lot of files I download have crap/spam in their filenames, e.g.

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

www.crap.com - file.name.ext

我已经想出了两种方式来处理他们,但他们似乎都pretty笨重:

I've come up with two ways for dealing with them but they both seem pretty clunky:

与参数扩展:

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

,然后用回声/ sed的:

and then with echo/sed:

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

我觉得像参数扩展为两个糟糕,但我喜欢它,因为我能够保持分配给进一步处理文件相同的变量重命名后(以上code是在使用脚本这就是所谓的每个文件的文件下载完成后)。

I feel like the parameter expansion is the worse of the two but I like it because I'm able to keep the same variable assigned to the file for further processing after the rename (the above code is used in a script that's called for each file after the file download is complete).

所以,无论如何,我希望有一个更好/更清洁的方式做到这上面有人更了解比我能告诉我,pferably $ P $的方式,让我很容易老的/原始变量重新分配给新/重命名的文件。

So anyway I was hoping there's a better/cleaner way to do the above that someone more knowledgeable than myself could show me, preferably in a way that would allow me to easily reassign the old/original variable to the new/renamed file.

感谢

推荐答案

由于有一些人不喜欢谁的Perl,我写的我的的bash的唯一版本。

Two answer: using perl rename or using pure bash

As there are some people who dislike perl, I wrote my bash only version

是的,这是一个典型的工作改名这是precisely设计的命令:

Yes, this is a typical job for rename command which was precisely designed for:

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

重命名所有 .JPG 从编号 1

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

那么匹配问题,以安全的方式完整的语法

有一个强大和安全的方式使用改名工具:

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

As this is perl common tool, we have to use perl syntax:

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

...等等...

... and so on...

......虽然你不使用 -f 标志改名命令它是安全的:文件韩元'T被overwrited,如果出现错误,你会得到一个错误信息。

... and it's safe while you don't use -f flag to rename command: file won't be overwrited and you will get an error message if something goes wrong.

我preFER通过使用专用的工具这样做,但这种甚至可以通过使用纯粹庆典(又名无任何叉)

I prefer doing this by using dedicated utility, but this could even be done by using pure bash (aka without any fork)

有没有使用任何其他二进制比bash的(没有 SED AWK TR 或其它):

There is no use of any other binary than bash (no sed, awk, tr or other):

#!/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

要使用文件作为参数来运行,样品:

To be run with files as argument, for sample:

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


  • 更换空间和括号由点

  • 更换序列 .- - - .. 仅由一个 -

  • 测试,如果文件名没有什么不同,有什么做的。

  • 测试,如果一个文件存在的 NEWNAME ...

  • 拆分文件名,计数器和扩展,为使索引的 NEWNAME

  • 循环,如果一个文件存在的 NEWNAME

  • Finaly重命名文件。

    • Replacing spaces and square bracket by dot
    • Replacing sequences of .-, -., -- or .. by only one -.
    • Test if filename don't differ, there is nothing to do.
    • Test if a file exist with newname...
    • split filename, counter and extension, for making indexed newname
    • loop if a file exist with newname
    • Finaly rename the file.
    • 这篇关于基于多模式更好的方法来重命名文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆