linux下rename用法--批量重命名 转

原文地址:http://www.javashuo.com/article/p-toquyrsg-cw.htmlcss

Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Linux发行版基本上使用的是C语言版本的,如今已经很难见到C语言版本的了, 因为历史缘由,在Perl语言大红大紫的时候,Linux的工具开发者们信仰Perl能取代C,因此大部分工具原来是C版本的都被Perl改写了,由于 Perl版本的支持正则处理,因此功能更增强大,已经再也不须要C语言版本的了。
 
1。如何区分系统里的rename命令是哪一个版本的?
 
输入man rename 看到第一行是
RENAME(1) Linux Programmer’s Manual RENAME(1)
那么 这个就是C语言版本的。【我查看系统上应该就是C语言版本的】
而若是出现的是:
RENAME(1)              Perl Programmers Reference Guide              RENAME(1)
这个就是Perl版本的了!
 
两个版本的语法差别:
C语言的,按照man上面的注解,
rename的语法格式是:
rename fromtofile
这个命令有三个参数,分别是from : 修改什么名字,to:改为什么名字,file 须要修改的文件是哪些。
用法示例:
好比,有一批文件,都是以log开头的,log001.txt,  log002.txt ....... 一直到log100.txt
如今想要把这批文件的log所有替换为history
rename  log history log*【C的用法~】
这句命令的意思很明白了,把 以log开头的全部文件中的log字符替换为history
这样替换后的文件是:history001.txt,  history002.txt ..... 一直到history100.txt
rename C语言版本的另外一个man示例是把后缀名批量修改,
好比咱们要将全部jpeg的后缀名图片文件修改成jpg文件。
rename .jpeg.jpg*.jpeg
这样,全部以.jpeg扩展的后缀名所有被修改成.jpg
如今总结一下:
 
rename C语言版本所能实现的功能:批量修改文件名,结果是每一个文件会被用相同的一个字符串替换掉!也就是说,没法实现诸如循环 而后按编号重命名!
 
2。Perl 版本的批量重命名,带有Perl的好处是,你可使用正则表达式来完成很奇特的功能。
 
perl 版本的参数格式:
rename  perlexprfiles
注意,perl版本的rename只有两个参数,第一个参数为perl正则表达式,第二个参数为所要处理的文件
man rename的帮助示例:
1) 有一批文件,以.bak结尾,如今想把这些.bak 通通去掉。
rename     's/\.bak$//'       *.bak
这个命令很简单,由于我尚未系统学习过perl,我不知道perl里替换字符串是否是这么干的,但sed是这么干的,因此若是你有sed或者tr基础,很容易明白,这个替换和sed里的正则语法是如出一辙的。
2) 把全部文件名内含有大小字母的,修改成小写字母。
rename      'y/A-Z/a-z/'      *
依然和sed的替换语法同样,不用多解释,若是看不懂的话,能够系统学习一下sed先。
还有几个比较实用的例子:
 
1) 批量去掉文件名里的空格
Linux文件名原本是不支持空格的,不知道何时容许了,固然,在命令行调用文件的时候,空格是颇有问题滴,好比你 原来能够直接  mv  oldfile  newfile  但有空格就不行了 , 得加双引号:mv "oldfile"  "newfile" 或者用反斜杠转移  \[] ,这样还好,但若是你直接把含有空格的图片名引入Latex文档,Latex生成pdf的时候会直接打印出文件名,以前这个问题苦恼了我好久,我生成的 pdf怎么总是出现文件名呢?后来才发现原来是文件名内含有空格的问题!windows系统下生成的文件名是天生含有空格的,虽然很讨厌,但有些惠普扫描 仪生成的图片默认就加入了空格,没有办法,只好去掉他,在系统研究rename命令前,我是用mv 去除空格的。
网上流程的两个去空格的版本:
 
1) tr 版:
find . -type f -name "* *" -print |
while read name; do
na=$(echo $name | tr ' ' '_')
if [[ $name != $na ]]; then
mv "$name" $na
fi
done
这个版本之前我一直用的,不知道哪一个网上搜刮来的,当时尚未系统的学习过tr/sed/awk命令。
注解一下,很好理解,find . type f -name "* *" -print 这一句是查找当前目录下全部类型为普通文件的 而且名字之中含有空格的文件,并打印出来,其实find默认就是打印的 这个-print 多余了,而后 经过管道传输给while 循环读取,文件名放到name 变量里,用tr 命令替换空格为下划线。 下面判断若是执行后的名称不相同,使用mv 命令重命名。但这个if判断无关紧要,由于find已经查询了全部文件名中含有空格的,那么通过tr 命令后,$na变量确定不等于$name 变量的。
因此这段代码能够简化:
find . -type f -name "* *" |
while read name; do
na=$(echo $name | tr ' ' '_')
mv "$name" "$na"
done
tr 能够看着是sed 的一个精简版本,tr 用下划线来替换空格。
还有一个 是sed 版本实现:
for f in *;do mv "$f" `echo "$f" | sed 's/[ ]\+/_/g' `; done
这里的sed表达式还能够这样写:
sed 's/[[:space:]]\+/_/g'
不过记住,sed里的出现一次或屡次的加号是须要添加反斜杠的。即:\+,这样就能够了。
好了,这两种办法都太他妈罗嗦了,看看rename实现吧:
rename      's/[ ]+/_/g'       *
OK就这么简单。
方括号内的空格能够用[:space:]代替,
便可以写成's/[[:space:]]+/_/g'
这里注意,rename 采用的是标准perl正则语法,因此无须将加号转变为反斜杠加号
即+ 不能修改成\+,不然替换失败。
 
还有几个好玩的例子:
好比统一在文件头部添加上hello 
rename         's/^/hello/'       *
统一把.html扩展名修改成.htm
rename          's/.html$/.htm/'      *
统一在尾部追加.zip后缀:
rename          's/$/.zip/'      *
统一去掉.zip后缀:
 
rename          's/.zip$//'      *
 
规则化数字编号名,好比1.jpg, 2.jpg ..... 100.jpg , 如今要使文件名所有三位即1.jpg .... 001.jpg
 
运行两次命令:
 
rename           's/^/00/'          [0-9].jpg     # 这一步把1.jpg ..... 9.jpg 变幻为001.jpg .... 009.jpg
 
rename            's/^/0/'           [0-9][0-9].jpg   # 这一步把10.jpg ..... 99.jpg 变幻为010.jpg ..... 090.jpg
 
Ok ,rename就研究了这么多,暂时不知道如何在rename中引入动态变量,好比$i++
 
我测试过i=0;  rename -n "s/^.*$/$((++i))/"   * 执行后i被自增了1,并不是想我想像中那样,能够在每操做一个文件自增一,猜测多是由于rename批量实现的,致使++i只计算一次!
 
 
 
-n  用来测试rename过程,并不直接运行,能够查看测试效果后,而后再运行。
好了,再次说明一下,你在使用的时候必定要确认一下你语言的版本,个人是C语言版本~
 
RENAME(1)                  Linux Programmer’s Manual                 RENAME(1)
 
功能:
 
 rename from to file...
 
用法:
 
For example, given the files foo1, ..., foo9, foo10, ..., foo278, the commands
              rename foo foo0 foo?
              rename foo foo0 foo??
       will turn them into foo001, ..., foo009, foo010, ..., foo278.
 
And
              rename .htm .html *.htm
       will fix the extension of your html files.
 
下面来看一个例子:html

最后再来个实际应用当中的问题,先看下如下的图~linux

看到了吧,咱们想把那个图片文件名中的ad字母换成big【注意:拷贝一份,不能直接替换】,那么想一想该怎么作呢,对了,就是用rename~
 
cd /data/openshop_1028/IMG_SERVER/sources/goods/
 
find ./ -name "*_ad.jpg" -exec cp "{}" {}.1 \;
 
find ./ -name "*_ad.jpg.1" -exec renamead.jpg.1 big.jpg {} \;
 
假如要是可以直接替换的话,那就一条命令了:
 
cd /data/openshop_1028/IMG_SERVER/sources/goods/
 
find ./ -name "*_ad.jpg" -exec rename ad big {} \;
 
能够看如下的测试~正则表达式

相关文章
相关标签/搜索