(一) Linux文件名转windows文件名

在Linux下对于文件的命名基本没有多大限制(不能有”/”),但是在windows下,文件名不允许有
\ / : * ? " < > |,所以如果需要复制文件的时候,在Linux下面命名正确的文件就需要检查命令规则,看是否满足windows的命名规则,主要是检查文件名时候有\ / : * ? " < > |这几个字符,然后将该字符转换为’-’。

 

这里介绍一个功能比较强大的重命名命令rename:

rename命令的格式:
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
-v, --verboseVerbose: print names of files successfully renamed.
-n, --no-actNo Action: show what files would have been renamed.
-f, --forceForce: overwrite existing files.

简单的rename使用命令:
字母的替换
rename "s/AA/aa/" *             //把文件名中的AA替换成aa
修改文件的后缀
rename "s/.html/.php/" *     //把.html 后缀的改成 .php后缀
批量添加文件后缀
rename "s/$/.txt/" *             //把所有的文件名都以txt结尾
批量删除文件名
rename "s/.txt//" *               //把所有以.txt结尾的文件名的.txt删掉

 

(1)         使用rename命令:由于双引号和”\”在rename命令中会被shell特殊功能扩展,所以暂时还不能替换这两个

find path -type f | xargs rename 's/[:*?<>|]/-/g'

(2)         使用sed命令:由于双引号和”\”在sed命令中会被shell特殊功能扩展,所以暂时还不能替换这两个(注意由于使用sh的时候会创建很多新进程效率较低)

find path -type f |

 sed -n 'h;s#.*/##;s#[:*?<>|]#-#g;ta; a:G;s#^[\n]∗[\n]∗\n.∗/.∗/[/]∗[/]∗$#mv \2\3 \2\1#' | sh –x

 

(二)批量修改同格式的文件名

如果要修改的文件名的格式一致,可以使用

(1)            find ./ -name xxx -exec mv {} {}.xx \

这个是最简单的了,但是有一点不好的是只能在后面加个后缀

(2)            find ./ -name xxx | xargs -I mv {} {}.xx

(3)            find ./ -name XXX | awk ''{printf("mv %s \t %s \n",$1,$1)}'' | sh

awk 里面可以自由发挥 单纯的对文件名处理来说 还不是awk的强项(注意由于使用sh的时候会创建很多新进程效率较低)

(4)            find ./ -name xxx | sed ''s/XXX/mv xxx xxxxx/'' | sh

(注意由于使用sh的时候会创建很多新进程效率较低)

(5)            ls | sed 's/.old$//'|xargs -I {} mv {}.old {}

创建进程的消耗是很大的,所以能用xargs的时候就不要用 |sh

 

 

rename 批量修改文件名

1.rename的用法

rename与mv的区别就是mv只能对单个文件重命名,而rename可以批量修改文件名

linux中的rename有两种版本,一种是C语言版的,一种是Perl版的。早期的Linux发行版基本上使用的是C语言版本,现在系统几乎都是Perl语言版本了,如何区分系统里的rename是哪个版本的,可以通过一下方式:

输入man rename 看到第一行中包含Linux Programmer’s Manual时,这就是C语言版本的,如果第一行中包含 Perl Programmers Reference Guide,则就是Perl版本的。

 

Perl语言版本的rename用法

perl版本的rename同sed中的语法类似,rename [-v/-n/-f] perl正则表达式 [待处理的文件]

  1. -v(verbose)打印被成功重命名的文件,即打印执行过程
  2. -n(no-act)只显示将被重命名的文件,而非实际进行重命名操作
  3. -f(force)覆盖已经存在的文件
  4. files需要被替换的文件(比如*.c、*.h),如果没给出文件名,将从标准输入读

常用的参数是-n,可以先用-n参数对一部小部分图片进行测试,每次执行命令会在terminal中把效果列出来,等确保没问题后去掉-n参数,再对全部数据进行统一处理。

 

举例:

将(1).jpg

(2).jpg

…..

改为:

test_001.jpg

test_002.jpg

……

1、去掉括号

rename -n 's/[()]//g' *.jpg

 

2、继续重命名为想要的格式

rename -n 's/^/test_00/' *.jpg

解释:

-n直接打印结果在终端中而非实际执行

s代表substitution,替换的意思

[()]代表匹配[]中的内容

//两个斜杠之间是空代表替换为空的内容,相当于删除

g代表全部匹配,不加g的话默认只会匹配一个括号

^-在文件名称开头加字符

test_00-将名称前面添加上test_00

规则化数字编号名

将1.jpg, 2.jpg ..... 100.jpg

改为:

001.jpg,002.jpg,...023.jpg,...100.jpg

1.把1.jpg ..... 9.jpg 变换为001.jpg .... 009.jpg

rename 's/^/00/'  [0-9].jpg

 

2. 把10.jpg ..... 99.jpg 变换为010.jpg ..... 090.jpg

rename 's/^/0/' [0-9][0-9].jpg 

 

去除文件名中空格

1.老方法

find . -type f -name "* *" -print |while read name; do mv "${name}" `echo "${name}"|sed "s/[ ]\+/_/g"`;done

 

2.rename方法

rename "s/[ ]+/_/g" *

● 其中[ ]+表示空格出现一次或多次,空格可以用[:space:]代替,该命令可替换为[[:space:]]+

● 在sed中需要将+转义,但在rename中不能转义,因为rename 采用的是标准perl正则语法

● 从命令中能够看到sed与rename的区别,rename处理的是该目录下所能匹配到的所有文件,它将所有文件名作为处理的对象,而命令sed 处理的是文件内容,所以只能通过echo "文件名"|sed "s/[ ]\+/_/g的方式才能处理文件名

批量修改文件前缀

场景:folder A中有a.rtv b.a.c.imu a.t.gps a.y.ew.imu等等,想要将这些文件的文件名统一为test,后缀保持不变

一般的思路:

1.遍历folder,依次获取文件

2.获取文件后缀${pre}

3.使用mv ${file}  test.${pre}

该方法中没有文件都要获取后缀再执行mv命令,灰常复杂

rename方法:

rename 's/.*\./test./' *

.*\.中.*代表匹配多次单个字符,\.代表对点进行转义。

其他:

 

 

rename 's/^/hello/' * 统一在文件头部添加上hello 

rename 's/.html$/.htm/' * 统一把.html扩展名修改为.htm

rename 's/$/.zip/' * 统一在尾部追加.zip后缀:

rename 's/.zip$//' * 统一去掉.zip后缀

 
  C语言版本rename的用法

     rename 原字符串 需改成的字符串 需要修改的文件

  rename 'test' 'tast' *.txt,将文件名中的test改为tast

  rename .jpeg .jpg *.jpeg  修改文件的扩展名

总的来说:rename C语言版本所能实现的功能:批量修改文件名,结果是每个文件会被相同的一个字符串替换掉!也就是说,无法实现诸如循环 然后按编号重命名等

 

2.Perl正则表达式

1.三种形式

匹配:m// 

(可以省略m,直接写成/regexp/)

替换:s/// 

s/PATTERN/REPLACEMENT/egimosx

e 将右侧作为表达式计算。

g 全匹配

i 不区分大小写的模式匹配

m 将字符串视为多行。

o 只编译一次模式,即使其中的变量发生变化。

s 将字符串视为单行。

x 使用扩展正则表达式

转化:tr/// 

转化有两种等价表达方式,如下:

tr/SEARCHLIST/REPLACEMENTLIST/cds

y/SEARCHLIST/REPLACEMENTLIST/cds

c 补充 SEARCHLIST.

d 删除找到但未替换的字符

s 压缩重复的替换字符

rename命令常用到替换和转化两种(用匹配也没意义)。转换跟替换不同,替换是将replacement整个字符串替换pattern字符串,而转换则是用replacementlist逐个字符替换searchlist逐个字符,结果依赖于replacementlist与searchlist字符个数,比如'tr/Sam/Stm/',用S替代S,t替代a,m替代m。

举例:

rename -n 'tr/Sam3/Stm/' FastSpiSam3C.nc

替换字符短,用最后一个字符m替换3

FastSpiSam3C.nc renamed as FtstSpiStmmC.nc

rename -n 'tr/Sam3/Stm32/' FastSpiSam3C.nc

替换字符长,多出字符被忽略

FastSpiSam3C.nc renamed as FtstSpiStm3C.nc

2.正则表达式中的一些常用模式

x?  匹配 0 次或一次 x 字符串

\d  匹配一个数字的字符,和 [0-9] 语法一样

x*  匹配 0 次或多次 x 字符串,但匹配可能的最少次数

\d+  匹配多个数字字符串,和 [0-9]+ 语法一样

x+  匹配 1 次或多次 x 字符串,但匹配可能的最少次数

\D  非数字,其他同 \d

.*  匹配 0 次或一次的任何字符

\D+  非数字,其他同 \d+

.+  匹配 1 次或多次的任何字符

\w   英文字母或数字的字符串,和 [a-zA-Z0-9] 语法一样

{m} 匹配刚好是 m 个 的指定字符串

\w+  和 [a-zA-Z0-9]+ 语法一样

{m,n}匹配在 m个 以上 n个 以下 的指定字符串

\W   非英文字母或数字的字符串,和 [^a-zA-Z0-9] 语法一样

{m,} 匹配 m个 以上 的指定字符串

\W+   和 [^a-zA-Z0-9]+ 语法一样

[]  匹配符合 [] 内的字符

\s    空格,和 [\n\t\r\f] 语法一样

[^] 匹配不符合 [] 内的字符

\s+   和 [\n\t\r\f]+ 一样

[0-9]匹配所有数字字符

\S    非空格,和 [^\n\t\r\f] 语法一样

[a-z]匹配所有小写字母字符

\S+   和 [^\n\t\r\f]+ 语法一样

[^0-9]匹配所有非数字字符

\b    匹配以英文字母,数字为边界的字符串

[^a-z]匹配所有非小写字母字符

\B    匹配不以英文字母,数值为边界的字符串

^   匹配字符开头的字符

a|b|c 匹配符合a字符 或是b字符 或是c字符 的字符串

$   匹配字符结尾的字符

abc   匹配含有 abc 的字符串