阳光烂灿的日子

--记录所有碎碎念

记一次 Rename 命令解决方案

| Comments

rename是Linux下的批量文件名更改工具。怎么好用以前也只不过是听说,今天有机会试用之。

正巧有一批文件,命名方式颇为奇特,

001ac.jpg  002ae.jpg 003.ag.jpg ... 012gf.jpg
是这么一个序列,前面是正常的数字序列,加两个冒似无序的字母,其实是也是有序的。要的结果是得到正常的
001.jpg 002.jpg 003.jpg ... 012.jpg

一开始想到的可以用bash的tr来做,冒似要写复杂的脚本,用来得到文件名,然后tr掉,然后再改名。

rename的用法是, rename a b * , 意思是把文件名里的a转换成b。

那么取得a到z的循环,执行两次 rename 或许能把字母给过滤掉。于是

#!/bin/sh
for i in {a..z}
do
   rename $i '' *.jpg
   rename $i '' *.jpg
done
能成吗?不能。结果是执行到 g 的时候把文件名的全换成 .jp的了,于是第二次rename找不到文件名。
不过rename还有第二个用法,就是改文件名。既然第一次换字母可能把文件名后缀给换掉,其实把文件名后缀先换成非字母就可以了。于是
#!/bin/sh
rename .jpg .89 *
for i in {a..z}
do
   rename $i '' *.89
   rename $i '' *.89
done
rename .89 .jpg *
即一开始就把后缀换成数字的,然后把字母全strip掉,然后再把数字后缀的换回正常的jpg后缀。
搞定了。

后续:

好吧,apporc把问题贴到stackoverflow了,那咱也来学习一下相关的bash技巧。
首先是apporc自己的方案:
  1 #!/bin/bash
  2
  3 for i in `find . -name "*.jpg"`
  4     do
  5         j=${i:0:3}
  6         echo $j
  7         mv $i $j.jpg
  8 done
看准了名字序列只有前面三个字母有效,于是取出来,重命名之。这方案很好啊,为啥他还说wired …

find . -name "*.jpg" | while read $name
do
    newName=${name:0:3}
    mv $i $j.jpg
done
这是David W的改写版本,获取方式不一样而已。然后看它下一个方案
for number in {1..100}
do
   zf_number=$(printf "%3d", $number)   #Zero fill number
   if [ -e ${zf_number}* ]
   then 
       mv ${zf_number}* $zf_number.jpg
   fi
done
这是先取得数字序列,然后通过匹配数字名的方法来改名,感觉繁琐了一点。

#!/bin/bash

for i in $( find . -name “*.jpg”) ;do
new=$(echo “$i” | sed ‘s/[A-Za-z.][A-Za-z.]*//g’)
echo $new
echo mv $i $new.jpg
done 这是另一个用户shellter的方案。直接是把文件名的字母全过滤掉,然后再重命名回来。不用说,它sed的正则用得很熟。

Comments