[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 系統管理 > 其它 > 正文
怎樣把 "*.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論壇

相關文章

======
 

★  樊強制作 歡迎分享  ★