Linux下批量修改文件名

Perl經典代碼之rename

Larry Wall的rename腳本, 只用了個位行數的代碼就構造出一個功能超強的批量文件重命名工具: 


註釋:


1.  # touch rename.perl        //創建一個文件:rename.perl  ,  內容如下。


2.  # chmod +x rename.perl


3.  # cp rename.perl /bin/


4.  # rename.perl  's/gongxu/leibie/g'  *    //將目錄中所有文件名中的 gongxu 替換爲 leibie


#!/usr/bin/perl -w
# rename - Larry's filename fixer
#用法: Perl表達式 [要處理的文件名]
$op = shift or die "Usage: rename expr [files]\n";

#如果沒有給出要處理的文件名則從標準輸入讀入
chomp(@ARGV = <STDIN>) unless @ARGV;

for (@ARGV) {
    $was = $_;
    eval $op; #對待處理的文件名($_)執行用戶輸入的Perl表達式$op
    die $@ if $@; #退出 , 如果eval出錯
    rename($was,$_) unless $was eq $_;
}


rename腳本的經典實例示範:


% rename.perl 's/\.orig$//' *.orig #移除文件末尾的.orig

% rename.perl "tr/A-Z/a-z/ unless /^Make/" * #所有非Make打頭的文件名大寫轉爲小寫

% rename.perl '$_ .= ".bad"' *.f #每個*.f文件後面追加一個.bad

% rename.perl 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i' * #回顯每個待處理的文件名, 等待輸入, 如果用戶輸入以y或Y打頭, 把文件名中的foo替換成bar

% find /tmp -name "*~" -print | rename.perl 's/^(.+)~$/.#$1/' #把 /tmp目錄裏面每個文件名末尾有~的文件名改成以.#開頭




http://www.linuxidc.com/Linux/2011-01/31594.htm


Linux的 rename 命令有兩個版本,一個是C語言版本的,一個是Perl語言版本的,早期的Linux發行版基本上使用的是C語言版本的,現在已經很難見到C語言版本的了,因爲Perl版本的支持正則處理,所以功能更加強大,已經不再需要C語言版本的了。


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


輸入 man rename 看到第一行是


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




那麼 這個就是C語言版本的。


而如果出現的是:
RENAME(1)              Perl Programmers Reference Guide              RENAME(1)


這個就是Perl版本的了!




兩個版本的語法差異:


1.C語言的,按照man上面的註解,
rename的語法格式是:


rename from to file


這個命令有三個參數,分別是 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的好處是,你可以使用正則表達式來完成很奇特的功能。


perl 版本的參數格式:


rename  perlexpr files


注意,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 去除空格的。



rename      's/[ ]+/_/g'        *



方括號內的空格可以用 [:space:]代替,
即可以寫成 's/[[:space:]]+/_/g'


這裏注意,rename 採用的是標準perl正則語法,所以無須將 加號轉變爲反斜槓加號
即 + 不能修改爲 \+,否則替換失敗。


還有幾個好玩的例子:
比如統一在文件頭部添加上 hello 
rename          's/^/hello/'        *


統一把.html擴展名修改爲 .htm
rename          's/.html$/.htm/'      *




統一在尾部追加 .zip後綴:
rename          's/$/.zip/'      *


統一去掉.zip後綴:
rename          's/.zip$//'      *


批量更改文件名 rename


通過 man rename 命令可以得知,rename 命令其實是一個 Perl 腳本命令,
它專用於批量地給多文件重命名(rename multiple files)。

命令格式:
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
perlexpr 是一種 Perl 腳本格式的正則表達式。
參數:
-v, --verbose
Verbose: print names of files successfully renamed.
詳細模式:打印成功更改的文件名列表
-n, --no-act
No Action: show what files would have been renamed.
測試模式:並不真正的執行命令,而只是顯示哪些文件名應該怎麼進行
更改,用於測試模式。
-f, --force
Force: overwrite existing files.
強制模式:在更改文件名,如果更改後的文件已經存在時覆蓋已經存在
的文件。


完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章