2011-08-16 31 views
2

我有文件,如列表:壳牌脚本(正则表达式来移动文件)

i60.st082313ea.jpg
i61.st51249c5e.jpg
i62.stef1fe5f2.jpg

我想通过将起始整数(例如60,61,62)递减1来重命名目录中的每个文件。

我做svn的 - 重命名使用类似以下的外壳:

for file in *.xml; 
    do svn mv $file `basename $file xml`json; 
done; 

但是,当涉及到创建一个正则表达式,并从文件的部分减去1,我在亏损。值得一提的是,该文件可能会在名称的其他地方重复表达i[0-9]+,因此它只需匹配前导字符串。

任何帮助/教程/链接真的很感激。

+2

哪个壳? –

+0

woops。在Ubuntu 11.04工作。 – onassar

+0

这不是一个外壳。 –

回答

2
for file in *.jpg; do 
    newfilename=`echo $file | awk -F '.' '{ OFS=".";print "i" substr($1,2,2)+1, $2, $3}'` 
    mv $file $newfilename 
done; 

注:这仅适用,如果文件名匹配的实例中(如整数是在第二和第三的位置,并将该文件具有刚好两个. S)。

HTH

+0

有无论如何,你可以包括扩展名为.jpg,.jpeg或.png的可能性吗? – onassar

+0

完美无缺地工作。谢谢! – onassar

+1

如果您的文件名有2个连续的空格,则可能无法使用。为了解决这个问题,可以用'echo'$ file“'改变'echo $ file',或者更好的改成'printf'%s \ n”,“$ file”'。 – jfg956

1

伟大的是,您的输入是非常规律的。因此,使用像

^i([0-9]+)(\..*)$ 

一个正则表达式将在输入的起点开始,符合“我”作为一个必要的字符,然后匹配一个十进制数,然后匹配输入的休息,直到结束。

圆括号使组可用于捕获匹配。如果您与bash匹配,捕获组可在BASH_REMATCH(一个数组)中使用。有了这个正则表达式,你有两个捕获组:你想减少的数字,以及文件名的其余部分。

要创建新文件名,您要连接字符'i',${BASH_REMATCH[1]} - 1${BASH_REMATCH[2]}

如果您与bash不匹配,请尝试使用perl? (另外,你可以使用\d作为我的特别喜爱的数字)。它在处理器上比sedawk重一点,但对于你想要做的事更容易。

sed支持反向引用,但要对它们进行算术运算,您必须从sed表达式(可执行)中调用shell命令。 awk并不真正支持反向引用,但gawk有一个帮助功能,gensub

1

,而无需创建为每个文件重命名的过程,并在bash shell中(你可以了解哪些外壳使用的是通过键入命令echo $SHELL),假设你的文件名总是'i'开头,后跟一个数字,然后由'.'

ls $.jpg | while read file; do 
    post_dot=${file#*.} 
    pre_dot=${file%%.*} 
    number=${pre_dot#i} 
    echo "mv "$file" "i$((number-1)).$post_dot"" 
done 

当你很高兴与打印结果,在mv行的末尾删除'echo "'开头和'"'。在mv命令中的大约$filei$((number-1)).$post_dot对于说明文件名中的空格很重要。

0

我写了一个小脚本我打电话mv_re虽然也许mv_evalmv_perl会更有意义:

#!/usr/bin/perl 

foreach (@ARGV) { 
    push(@evals,$_); 
} 

sub mv_eval { 
    my ($dirname) = @_; 
    opendir (my($dh), $dirname) or 
     die "Couldn't open dir '$dirname': $!"; 
    my @fs = readdir $dh; 
    foreach $f (@fs) { 
     $_ = $f; 
     foreach $e (@evals) { eval $e; } 
     print "mv '$f' '$_'\n" if ($_ ne $f); 
    } 
    closedir $dh; 
} 

mv_eval("."); 

它把每个参数的行Perl代码,并在当前直接运行他们对每一个文件名。任何更改的文件名都会打印出适当的mv命令。因此mv_re s/www.//写入脚本以从当前目录中的每个文件中删除第一个www.

理想情况下,我应该为目录或filespec添加可选的命令行参数,替代命令为mv,以及一个选项,而不是为用户编写脚本。