複製鏈接
請複製以下鏈接發送給好友

rename

(Linux命令)

鎖定
rename,是一條Linux命令,用於給文件重命名,可以進行批量文件重命名。
外文名
rename
功    能
給文件重命名
地    方
計算機

目錄

  1. 1 比較
  2. 2 區分
  3. 歷史
  4. 識別
  5. 差異
  6. 詳解

rename比較

rename和mv區別
Linux中rename和mv都可以對文件重命名,在此對rename命令和mv命令在重命名文件方面做一個比較。
可以看到mv命令確實有重命名的功能,但是實際應用中,它只能對單個文件重命名,命令如下:
mv [path/]oldfilename [path/]newfilename
"mv命令只能對單個文件重命名",這就是mv命令和rename命令的在重命名方面的根本區別。
再來説rename命令,rename命令是專用於文件重命名的,而且根據其後的例子可以看出,rename除了給單個文件重命名,還可以批量文件重命名。

rename區分

rename歷史

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

rename識別

區分rename命令的版本
輸入man rename看到第一行是
RENAME(1) Linux Programmer’s Manual RENAME(1)
那麼這個就是C語言版本的。
而如果出現的是:
RENAME(1) Perl Programmers Reference Guide RENAME(1)
這個就是Perl版本的了!

rename差異

兩個版本的語法基本差異
C語言的參數格式
按照man上面的註解,rename的語法格式是:
rename from to file
這個命令有三個參數,分別是from : 修改什麼名字,to:改成什麼名字,file 需要修改的文件是哪些。
Perl版本的參數格式
rename perlexpr files
注意,Perl版本的rename只有兩個參數,第一個參數為Perl正則表達式,第二個參數為所要處理的文件

rename詳解

C語言版本的rename
值得注意一點的是,C語言版本的rename命令是帶3個參數而不是很多人認為的2個參數。
上面的例子中給出了兩種文件批量重命名的用法,而實際上,rename結合通配符使用,它的功能比上面的例子所顯示的更強大。基本的通配符有以下幾個:
? 可替代單個字符
* 可替代多個字符
[charset] 可替代charset集中的任意單個字符
rename把文件名中的第一個參數字符串用第二個參數替換,只替換符合第三個參數模式的文件名。
下面以例子加以説明:
如文件夾中有這些文件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。
Perl語言版本的rename
帶有Perl的好處是,你可以使用正則表達式來完成很奇特的功能。
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過程,並不直接運行,可以查看測試效果後,然後再運行。
好了,再次説明一下,你在使用的時候一定要確認一下你語言的版本……