Linux批量重新命名 rename & mv

來源:互聯網
上載者:User

剛學習linux的時候,對檔案重新命名首先想到的就是rename命令,但是按照 在windows下對檔案重新命名的方式試了N多次都沒有反應,在網上一搜尋,發現很多人都對rename命令知之甚少,甚至有一部分人說linux下沒有 rename命令,建議大家用mv命令。鑒於此,於是man rename一下,好好的研究了一下它的用法 ,在此對rename命令和mv命令在重新命名檔案方面做一個比較,有不足之處,希望各位博友指正!

首先來說一下mv命令,在man mv中我們可以看到對於mv命令的介紹是這樣的:

mv -move(rename) files

可以看到mv命令確實有重新命名的功能,但是實際應用中,它只能對單個檔案重新命名,命令如下:

mv [path/]oldfilename [path/]newfilename

“mv命令只能對單個檔案重新命名”,這實就是mv命令和rename命令的在重新命名方面的根本區別。

再來說rename命令,在man rename的說明如下:

NAME

rename -Rename files

SYNOPSIS

rename from to file....

DESCRIPTION

rename will rename the specified files by replacing the first occurrence of from in their name by to.

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.

可以看出rename命令是專用於檔案重新命名的,而且根據其後的例子可以看出,rename除了給單個檔案重新命名,還可以批量檔案重新命名。同時,值得注意一點的是,rename命令是帶3個參數而不是很多人認為的2個參數。

上面的例子中給出了兩種檔案批量重新命名的用法,而實際上,rename結合萬用字元使用,它的功能比上面的例子所顯示的更強大。基本的萬用字元有以下幾個:

? 可替代單個字元

* 可替代多個字元

[charset] 可替代charset集中的任意單個字元

下面以例子加以說明:

如檔案夾中有這些檔案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。

在使用中,三種萬用字元可以一起結合使用,關於具體的其它用法就只有自己不斷的摸索了

 

或者用程式設計語言

Linux批量重新命名檔案會涉及到改變一個字母、改變一些相連字母、改變某些位置的字母、在最前面加上某些字母、或者改變字母的大小寫。完成這裡五個方法基本上就會解決了Linux批量重新命名的工作。

1、我想把它們的名字的第一個1個字母變為"q",其它的不變

[root@pps mailqueue]# for i in `ls`; do mv -f $i `echo $i | sed 's/^./q/'`; done

或者寫個指令碼,顯得更加清晰:

  1. for file in `ls`
  2. do
  3.   newfile =`echo $i | sed 's/^./q/'`
  4.  mv $file $newfile
  5. done



2、修改前面5個字母為zhaozh

[root@pps mailqueue]# for i in `ls`; do mv -f $i `echo $i | sed 's/^...../zhaozh/'`; done

3、修改後面5個字母為snail

[root@pps mailqueue]# for i in `ls`; do mv -f $i `echo $i | sed 's/.....$/snail/'`; done

4、在前面添加 _hoho_

[root@pps mailqueue]# for i in `ls`; do mv -f $i `echo "_hoho_"$i`; done

5、所有的小寫字母變大寫字母

[root@pps mailqueue]# for i in `ls`; do mv -f $i `echo $i | tr a-z A-Z`; done

  

 

=================================================

Linux rename命令 批量重新命名

Linux的 rename 命令有兩個版本,一個是C語言版本的,一個是Perl語言版本的,早期的Linux發行版基本上使用的是C語言版本的,現在已經很難見到C語言版本的了, 由於曆史原因,在Perl語言大紅大紫的時候,Linux的工具開發人員們信仰Perl能取代C,所以大部分工具原來是C版本的都被Perl改寫了,因為 Perl版本的支援正則處理,所以功能更加強大,已經不再需要C語言版本的了。

 


如何區分系統裡的rename命令是哪個版本的?

輸入 man rename 看到第一行是

RENAME(1) Linux Programmer’s Manual RENAME(1)

那麼 這個就是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*

這句命令的意思很明白了,把 以 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; 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過程,並不直接運行,可以查看測試效果後,然後再運行。

 

 

[轉] http://apps.hi.baidu.com/share/detail/24003061

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.