您的位置:首页 > 其它

rename()

2016-07-13 08:51 369 查看


同义词rename()一般指rename

rename函数功能是给一个文件重命名,用该函数可以实现文件移动功能,把一个文件的完整路径的盘符改一下就实现了这个文件的移动。具体参见下面的程序示例说明。

外文名rename添加概述  类    型函数功    能给一个文件重命名地    方计算机

目录

1C语言库函数
2dos命令
简介
应用举例
3Linux命令
1.区分rename命令的版本
2.两个版本的语法基本差异
3.C语言版本的rename
4.perl语言版本的rename

C语言库函数

编辑
头文件:在Visual C++6.0中用stdio.h或者io.h
用 法: int rename(char *oldname, char *newname);
程序例:
#include <stdio.h>
int main(void)
{
char oldname[80], newname[80];
/* prompt for file to rename and new name */
printf("File to rename: ");
gets(oldname);
printf("New name: ");
gets(newname);
/* Rename the file */
if (rename(oldname, newname) == 0)
printf("Renamed %s to %s.\n", oldname, newname);
else
perror("rename");
return 0;
}
执行过程:
File to rename: D:\\in.dat
New name: G:\\in.dat
Renamed D:\\in.dat to G:\\in.dat.
这样就实现了in.dat从D盘移动到G盘。
在unix或linux系统中:
#include <stdio.h>
int rename(const char *oldname, const char *newname);
函数说明
(1) 如果oldname为一个文件而不是目录,那么为该文件更名。在这种情况下,如果newname作为一个目录已存在,则它不能重命名一个目录。如果newname已存在,而且不是一个目录,则先将其删除然后将oldname更名为newname。对oldname所在目录以及newname所在的目录,调用进程必须具有写许可权,因为将更改这两个目录。
(2) 如若oldname为一个目录,那么为该目录更名。如果newname已存在,则它必须是一个目录,而且该目录应当是空目录(空目录指的是该目录中只有. 和.. 项)。如果newname存在(而且是一个空目录),则先将其删除,然后将oldname更名为newname。另外,当为一个目录更名时,newname不能包含oldname作为其路径前缀。例如,不能将/usr更名为/usr/foo/testdir,因为老名字( /usr/foo)是新名字的路径前缀,因而不能将其删除。
(3) 作为一个特例,如果oldname和newname引用同一文件,则函数不做任何更改而成功返回。
返回值 执行成功则返回0,失败返回-1,错误原因存于errno
范例
#include <stdio.h>
int main(int argc,char **argv)
{
if(argc < 3)
{
printf("Usage: %s old_name new_name\n",argv[0]);
return -1;
}
printf("%s => %s\n", argv[1], argv[2]);
if(rename(argv[1], argv[2]) < 0 )
printf("error!\n");
else
printf("ok!\n");
return 0;
}

dos命令

编辑

简介

功能:重命名文件或文件夹
用法:rename 完整路径文件名(文件夹名) 新文件名(新文件夹名)
ren 完整路径文件名(文件夹名) 新文件名(新文件夹名)

应用举例

例子:
如想修改D盘下的文件1.txt为2.txt可以在cmd中执行命令
ren d:\1.txt 2.txt
如想修改D盘下的文件夹old为文件夹new可以在cmd中执行命令
ren d:\old new

Linux命令

编辑
linux中rename和mv都可以对文件重命名,在此对rename命令和mv命令在重命名文件方面做一个比较。
可以看到mv命令确实有重命名的功能,但是实际应用中,它只能对单个文件重命名,命令如下:
mv [path/]oldfilename [path/]newfilename "mv命令只能对单个文件重命名",这实就是mv命令和rename命令的在重命名方面的根本区别。
再来说rename命令,rename命令是专用于文件重命名的,而且根据其后的例子可以看出,rename除了给单个文件重命名,还可以批量文件重命名。
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语言版本的。
而如果出现的是:
RENAME(1) Perl Programmers Reference Guide RENAME(1)
这个就是Perl版本的了!

2.两个版本的语法基本差异

C语言的参数格式
按照man上面的注解,rename的语法格式是:rename from to file
这个命令有三个参数,分别是from : 修改什么名字,to:改成什么名字,file 需要修改的文件是哪些。
perl版本的参数格式
rename perlexpr files
注意,perl版本的rename只有两个参数,第一个参数为perl正则表达式,第二个参数为所要处理的文件

3.C语言版本的rename

值得注意一点的是,
C语言版本的rename命令是带3个参数而不是很多人认为的2个参数。
上面的例子中给出了两种文件批量重命名的用法,而实际上,rename结合通配符使用,它的功能比上面的例子所显示的更强大。基本的通配符有以下几个:
? 可替代单个字符
* 可替代多个字符
[charset] 可替代charset集中的任意单个字符
rename把文件名中的第一个参数字符串用第二个参数替换,只替换符合第三个参数模式的文件名。
下面以例子加以说明:
如文件夹中有这些文件foo1, ..., foo9, foo10, ..., foo278,如果使用
rename foo foo0 foo?
则它只会把foo1到foo9的文件重命名为foo01到foo09,因为?通配符只能替代单个字符,所以被重命名的文件只是有4个字符长度名称的文件,文件名中的foo被替换为foo0。
再继续使用
rename foo foo0 foo??
则文件夹中的foo01到foo99的所有文件都被重命名为foo001到foo099,而foo100及其以后的文件名都不变,因为通配符?的使用,所以只重命名5个字符长度名称的文件,文件名中的foo被替换为foo0。
如果再继续使用
rename foo foo0 foo*
则foo001到foo278的所有文件都被重命名为foo0001到foo0278,因为通配符*可替代多个字符,所以,所有以foo开头的文件都被重命名了,文件名中的foo被替换为foo0。
我们再来看通配符[charset]的用法,还是继续在上面所说的文件夹中,执行如下命令
rename foo0 foo foo0[2]*
则从foo0200到foo0278的所有文件都被重命名为foo200到foo278,文件名中的foo0被替换为foo。

4.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过程,并不直接运行,可以查看测试效果后,然后再运行。
好了,再次说明一下,你在使用的时候一定要确认一下你语言的版本……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: