標籤:

Perl-目錄操作

(1)在目錄樹中移動

chdir 路徑名

類似於linux中的cd命令,在程序中可更改執行路徑。若返回假值,則表明有些事情沒有順利完成。

(2)文件名通配

glob操作符。

my @all_files=glob *;my @pm_files=glob *.pm;

@all_files獲取當前目錄所有文件並按字母排序,但不包括以點號開頭的文件,@pm_files得到的列表與在命令行中使用echo結果相同。

如果一次匹配多種模式,可以在參數中用空格隔開各個模式。

#顯示/tmp和/home目錄下所有文件$dir="/tmp/* /home/*";@files=glob($dir);#獲取所有文件名,無論是否以點號開頭my @all_files=glob * .*;#下述寫法功能相同my @all_files=glob *;my @all_files=<*>;

(3) 目錄句柄

opendir DIRHEADER,EXPR #打開目錄

readdir DIRHEADER #讀取目錄

closedir DIRHEADER #關閉目錄

讀取的是目錄下的文件名而不是文件。使用通配可以獲取更高的性能。

目錄句柄返回的名稱列表並未按照任何特定順序排序,列表裡將包含所有的文件,而不是匹配某些模式的部分。包括.和..。

readdir返回的文件名並不包含路徑名(glob操作包含路徑名),只是目錄中的文件名而已,無法對文件名進行文件測試。要想進行文件測試,需加上路徑名。下述示例通過目錄句柄進行文件讀取並判斷每個文件的類型。

#! /bin/perl -wuse strict;use autodie;use 5.010;#指定目錄。獲取目錄下所有文件並判斷屬性my $dir=$ARGV[0];opendir (my $dh,$dir );foreach my $file(readdir $dh){ $file="$dir/$file"; #必須帶上路徑名才能進行文件測試 print"$file ";if(-f $file){ say "a ordianry file";}if(-d $file){ say "a dictionary";}}closedir $dh;

(4) 刪除文件

unlink操作符,刪除指定的文件列表:

unlink qw(slate bedrock lava);

unlink的參數為一個列表,可結合glob一次刪除多個文件

unlink glob 『.o』#等價於shell中的rm *.o

unlink 返回值代表成功刪除的文件數目

unlink操作失敗後內置的$!將會被設成操作系統錯誤的相關信息(僅在循環處理每一個文件的過程中才可用,因為每次調用失敗時都會重設改變數)。

unlink不能用來刪除目錄。

(5)重命名文件

rename old,new;

rename執行失敗時返回假,並且會將操作系統返回的錯誤信息存到$!內。

rename也可以將文件移到別的目錄中去。

下述代碼展示了如何批量把名稱以.old結尾的文件改名為以.new結尾。

foreach my $file(glob "*.old"){ my $newfile=$file; $newfile=~s/.old$/.new/ #(斜線中左邊是正則表達式部分,需反斜線,右邊可視為雙引號內的字元串,不需要反斜線) if(-e $newfile) { warn "cant rename $file to $newfile:$newfile exists
"; } elsif(rename $file=>$newfile){ } else { warn "rename $file to $newfile failed:$!
"; }}

(6)鏈接與文件

目錄是一份文件名和相應inode編號的對照表。目錄列出來的內容有兩個特殊條目:一個是點(.),代表目錄本身;另一個則是(..),指的是目錄結構中的高一層目錄。

要在指定的目錄中創建一個新文件時,系統會增加一個條目來記錄文件名與新的inode編號。每個inode都有自己的鏈接數。如果inode並未在任何目錄中出現,它的鏈接數就一定是零。因而所有鏈接數為0的點都可以用來存放新的文件。任何目錄的鏈接數都至少是2:一個位於它的上層目錄的列表裡,另一個位於它本身的列表裡。若裡面有子目錄,則每個子目錄還會通過..條目再增加一個鏈接。鏈接數目代表該inode的真實名稱的數量。

硬鏈接:link 『chicken』,『egg』;#為chicken創建硬鏈接egg

chicken和egg均指向磁碟同一處(inode相同)。如果刪除了chicken,文件數據並不會丟失,因為還可以通過egg來訪問。

在目錄列表中所有inode指向的文件都必須在同一個掛載卷中。如果要跨磁碟移動文件,就必須重新部署inode數據。

硬鏈接的另一限制就是不能為目錄創建額外的名稱(目錄必須按照層次排列)。

符號鏈接(軟鏈接):目錄里的特殊條目,用來高速系統實際文件放置在別的地方。但並不會增加inode的軟鏈接數。

symlink 『dodgson』,carroll #為dodgson創建軟鏈接carroll

符號鏈接可以跨文件系統為目錄建立軟鏈接。符號鏈接能指向任何文件名,而不管它放在哪個目錄里,甚至還可以指向不存在的文件。不過軟鏈接不像硬鏈接那樣可以防止數據丟失,因為它並不會增加inode的鏈接數。

要去的符號鏈接指向的位置,可使用readlink,返回符號鏈接指向的位置。如果參數不是符號鏈接,則返回undef。

my $where =readlink carroll; #得到dodgson

兩種鏈接都可以使用unlink移除。

(6)創建和刪除目錄

mkdir:在現有目錄下創建新目錄;

mkdir 『fred』,0755;#第二個參數表示目錄的許可權(8進位)。

相當成數字用的字元串計時以0開頭,也不會被解釋成八進位數,下述寫法是錯誤的:

my $name="fred";my $permissions="0755";mkdir $name,$permisssions;

0755會被當成十進位處理,要解決這個問題,應使用mkdir $name,oct($permisssions);

rmdir:移除空目錄,每次只能刪除一個目錄。如果對非空目錄調用rmdir函數會導致失敗。可先用unlink刪除目錄中的內容,再試圖移除已經清空的目錄。若含有子目錄,可使用perl自帶的file::Path模塊的rmtree函數。

(7)修改許可權

chmod 0755 ,『fred』,barrney;

chmod會返回成功更改的條目數量。

(8)修改隸屬關係

可使用chown函數來更改一系列文件的擁有者以及其所屬組。擁有者和所屬組會被同時更改,並且在指定時必須給出數字形式的用戶標識符及組標識符。

my $user =1004;my $group=100;chown $user,$group,glob(*.o);

如果要處理的不是數字,而是字元串,使用getpwnam函數將用戶名轉換成用戶編號,用getgrnam函數把用戶組轉換成組編號:

defined(my $user =getpwnam merlyn) or die bad user;defined(my $group=getgrnam users) or die bad group;chown $user,$group,glob(*.o);

成功返回後,chown函數會返回受影響的文件數量。在發生錯誤時在$!中設定出錯信息。

(9)修改時間戳

utime:可以用來修改某個文件最近的更改或訪問時間。其前兩個參數是新的訪問時間和更改時間,其餘參數就是要修改時間戳的文件名列表。時間格式採用內部時間戳的格式。

my $now=time;my $ago=$now-24*60*60;#一天的秒數utime $now,$ago,glob *;

文件有任何改動時,其第三個時間戳(ctime)會被設為now,utime無法更改它。這個ctiem主要是給增量備份的程序用的:如果某個文件的ctiem比磁帶上的新,那麼它就該再次備份了。


推薦閱讀:

如何評價唐鳳(唐宗漢)這個人?
學Perl還是Python?
長鋏的《屠龍之技》講了什麼?感覺凌亂、深奧
Perl 文件操作
生信分析人員如何系統入門perl

TAG:Perl |