@linux下rename用法–批量重新命名@

來源:互聯網
上載者:User

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的好處是,你可以使用Regex來完成很奇特的功能。

perl 版本的參數格式:
rename  perlexprfiles
注意,perl版本的rename只有兩個參數,第一個參數為perlRegex,第二個參數為所要處理的檔案
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; dona=$(echo $name | tr ' ' '_')if [[ $name != $na ]]; thenmv "$name" $nafidone

這個版本以前我一直用的,不知道哪個網上搜刮來的,當時還沒有系統的學習過 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; dona=$(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.

下面來看一個例子:

最後再來個實際應用當中的問題,先看下以下的圖~


看到了吧,我們想把那個圖片檔案名稱中的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.1big.jpg {} \; 

假如要是能夠直接替換的話,那就一條命令了:

cd /data/openshop_1028/IMG_SERVER/sources/goods/

find ./ -name "*_ad.jpg" -exec rename
ad big {} \;

可以看以下的測試~

其實還可以用指令碼,也就是用個迴圈語句~

#!/bin/sh#mail:zhuying.jz.137@163.comfor file in `ls ./*_ad.jpg` do rename=`echo "${file}.1"`/bin/cp $file $rename/bin/mv $rename `echo "${rename%ad*}big.jpg"` #這裡就是變數的截取新方法,在shell編程課程中會用到此用法。done

其實關於.*和*的問題我有時候也有點糊塗,例如以下:

[oracle@sor-sys ~]$ echo ${PATH##.*:}/usr/local/ruby-1.8.7-p330/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.6.0_05/bin:/usr/local/maven/bin:/root/bin:/usr/local/jdk1.6.0_05/bin:/home/oracle/bin[oracle@sor-sys ~]$ echo ${PATH##*:}/home/oracle/bin

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.