[ 永远的UNIX::UNIX技术资料的宝库 ]

首页 > 系统管理 > 其它 > 正文
怎么样把 "*.foo" 改名为 "*.bar" 呢?怎样把档案名称改成小写呢?
Steve Hayman (2001-04-19 10:31:08)
为什么 "mv *.foo *.bar" 不对呢? 想想 shell 是怎样把万用字元展开的 
吧。 在 mv 读取参数前 "*.foo" 与 "*.bar" 就已经展开了。"mv *.foo 
*.bar" 在各种不同的 shell 会有不同的结果。 Csh 的话会印出 "No 
match",因为找不到 "*.bar"。 Sh 则是会执行 "mv a.foo b.foo c.foo 
*.bar",也就是说如果只有在有一名为 "*.bar" 的子目录存在时 mv 才会 
认为执行成功,不过就算成功也不是你所预期的结果。 

正确的做法是用你所用的 shell 提供的回圈来做。若你的系统中有 
"basename" 这个指令: 

C Shell: 
        foreach f ( *.foo ) 
            set base=`basename $f .foo` 
            mv $f $base.bar 
        end 

Bourne Shell: 
        for f in *.foo; do 
            base=`basename $f .foo` 
            mv $f $base.bar 
        done 

有些 shell 会提供就自己的变数替代功能,那就可以不用 "basename", 
而用更简单的回圈了: 

C Shell: 

        foreach f ( *.foo ) 
            mv $f $f:r.bar 
        end 

Korn Shell: 

        for f in *.foo; do 
            mv $f ${f%foo}bar 
        done 

如果没有 "basename" 可用或是胍鱿癜?nbsp;foo.* 改名为 bar.* 之类的 
事,那么可以用其他的方法如 "sed" 把原来的档案名称做分隔的动作,但 
是回圈的想法是一样的。你也可以利用 "sed" 把档名转换成 "mv" 的命令 
,然后再把这些命令转给 "sh" 执行。如下: 

        ls -d *.foo | sed -e 's/.*/mv & &/' -e 's/foo$/bar/' | sh 

在 1990 年 4 月时,Vladimir Lanin 把他自己写的一个叫 "mmv" 的程式 
post 到 comp.sources.unix (Volumn 21, issues 87 and 88),这个程式 
就能够把这件事处理得很好。 你可以这样使用: 

        mmv '*.foo' '=1.bar' 

以上所提的 shell 中的回圈也可以用来做档案名称的大、小写转换。你可 
以用改档名的方式把大写档名改为小写: 

C Shell: 
    foreach f ( * ) 
        mv $f `echo $f | tr '[A-Z]' '[a-z]'` 
    end 

Bourne Shell: 
    for f in *; do 
        mv $f `echo $f | tr '[A-Z]' '[a-z]'` 
    done 

Korn Shell: 
    typeset -l l 
    for f in *; do 
        l="$f" 
        mv $f $l 
    done 

如果你还希望能处理含有特殊字元(空白或其他的奇怪字元)的档名,那 
么你最好用: 

Bourne Shell: 

    for f in *; do 
      g=`expr "xxx$f" : 'xxx\(.*\)' | tr '[A-Z]' '[a-z]'` 
      mv "$f" "$g" 
    done 

'expr' 不管档名里有没有特殊字元都会印出档名。 

有些版本的 "tr" 需要用 '[' 和 ']',有些则不必。不过,不管是不是一 
定要用 '['  与 ']' 的 "tr",加了总是没有害处。 

若你的系统里有装 "perl",那你可以用 Larry Wall 写的这个多用途改档 
名的程式。 

#!/usr/bin/perl 
# 
# rename script examples from lwall: 
#       rename 's/\.orig$//' *.orig 
#       rename 'y/A-Z/a-z/ unless /^Make/' * 
#       rename '$_ .= ".bad"' *.f 
#       rename 'print "$_: "; s/foo/bar/ if  =~ /^y/I' * 

$op = shift; 
for (@ARGV) { 
     $was = $_; 
     eval $op; 
     die $@ if $@; 
     rename($was,$_) unless $was eq $_; 
} 
(http://www.fanqiang.com)
    进入【UNIX论坛

相关文章

===更多相关===
 

★  樊强制作 欢迎分享  ★