• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Perl小技巧:文件操作

    發表于:2007-06-11來源:作者:點擊數: 標簽:
    *找到具有指定特征的文件* $path = "/path/to/dir/";opendir DIR, $path;@arr1 = readdir DIR;@arr2 = grep{-T "$path$_"} @arr1; #text files only@arr3 = grep{!-d "$path$_"} @arr1; #no directories@arr4 = grep{-s "$path$_" 1024} @arr1; #less than 1K
    *找到具有指定特征的文件*
    $path = "/path/to/dir/";
    opendir DIR, $path;
    @arr1 = readdir DIR;
    @arr2 = grep{-T "$path$_"} @arr1; #text files only
    @arr3 = grep{!-d "$path$_"} @arr1; #no directories
    @arr4 = grep{-s "$path$_" < 1024} @arr1; #less than 1K
    
    代碼解釋:假如被測試的目錄項是一個文本文件,那么 -T 文件操作符就會返回真。其實針對目錄項的測試操作還有很多。(注:文件和目錄在系統中都是以目錄項的形式來管理的,所以要區別一個目錄項指向的是一個文件還是一個目錄需要相應的操作符)。注意上面的 readdir 函數返回指定目錄下的所有目錄項。因為在 grep 函數中對目錄項的測試需要文件的完全路徑,所以我們把 $PATH(存儲了目錄項的部分路徑) 和 $_(存儲了目錄項的名字)中的內容聯合起來得到文件的完全路徑 *對目錄進行遞歸搜索*
    use File::Find;
    
    find(\&handleFind, 'imac:documents:code');
    
    sub handleFind{
        my $foundFile = $File::Find::name;
        print "$foundFile\n" if ($foundFile =~ /\.html?$/i);
    }
    
    RESULT: imac:documents:code:index.html imac:documents:code:perl:example.HTM 運行結果: 代碼討論:那些工作于 Unix 系統的 Perl 程序員可以非常簡便的利用 UNIX 上提供的工具來完成許多日常的工作,比如遞歸的列出指定目錄下的所有目錄項(也就是列出指定目錄及指定目錄子目錄下的所有目錄項目)。然而 Perl 的一個最大的特征就是可以運行于很多的平臺上。所以如果你碰巧工作在一個非 UNIX 的平臺,或者如果你雖工作在 UNIX 平臺,但不喜歡使用系統工具寫腳本,你可以選擇 Perl。要完成這些巧妙的工作,你需要使用 perl 中的 File:Find 模塊。當你加載了這個模塊的時候,你就可以使用其中的 find 子函數,在調用這個函數的時候,需要帶參數:第一個參數是一個函數的引用,這個函數由你自己建立,每次一個文件被找到的時候,它都會運行。接下來的一個參數是一串你想要搜索的路徑。我寫的這個示例腳本是運行在 Macintosh OS 8.x 系統上的,所以我使用了 Mac 系統的路徑分隔符 :。如果是在 Windows,你可以用反斜杠,如果是在 Unix 系統則是正斜杠(至于在 Amiga 系統上用什么我就不知道了)??傊?,find 函數將會在每次找到一個文件的時候調用你給出的子函數,而且會對子目錄進行查找。在我的 handledfind 子函數中,我通過這個模塊特定變量 $File::Find::name 來獲得每次 find 找到的文件名。然后,就可以對該文件執行任何你想的測試,在上面的例子中,我們輸出有 .html 的擴展名文件名。 *文件讀操作* *一次讀入整個文件內容。*
    open FH, "< anthem";
    $/ = undef;
    $slurp = ;
    print $slurp;
    
    運行結果:一下就顯示了所有的文件內容,此刻你應該非常的自豪。:) 代碼討論:尖括號 <> 對文件句柄進行操作,在標量上下文中它將返回文件的下一條記錄,在數組上下文中它將返回所有的記錄。在默認的情況下,文件中的記錄被認為是由換行符分開(例如回車或其他代表新行開始的字符)。你可以重新設定這個默認的分隔符,然后 Perl 將會以你指定的分隔符為準來替代換行符。全局變量 $/ 里存儲了輸入文件的分隔符,如果你把 $/ 的值設置為 undef ,那么 Perl 將會認為整個文件是一條記錄(因為此刻已經沒有文件分隔符了)。牢記 $/ 是全局變量,千萬不要在腳本的其他地方不經意的改變它,這個錯誤將很難被發現。你可能會問,我們能否不改變 $/,而采用把文件的所有記錄讀到一個數組中,然后把數組聯合成一個很長的字符串(比如 $slurp = join("",);)的方法實現一次讀入文件。當然這也是一個有效的解決辦法,但是你會發現它很慢,是否選用它取決你的應用,取決于你是否關心運行速度。 *賦值* *把一個文件句柄賦給另一個文件句柄*
    open(MYOUT, "> bottle.txt");
    *STDOUT = *MYOUT;
    print "message";
    
    運行結果:文本文件 bottle.txt 現在包含 message 字符串。代碼討論:以前可能你配合使用過 Print 函數和文件句柄,但是你是否知道就算你沒有使用文件句柄,Perl 也默認你在使用一個稱為 STDOUT 的句柄?C 程序員知道 STDOUT 代表標準輸出,也就是通常的屏幕,或終端窗口(或者是 CGI 程序的輸出端 - 瀏覽器)。在這里我們完成的工作是創建我們自己的文件句柄,它指向一個給定的文件,然后我們做了一件比較鬼的工作,使用 * 前綴把 STDOUT 轉換為 typeglob 類型。Typeglob 類型的數據可以有別名,這樣一個變量可能會指向另一個其他名字的變量。上面第二行代碼使 STDOUT 指向 MYOUT 變量。所以執行 print 操作時的默認輸出對象也就成為了我們創建的文件句柄。 *同時向兩個文件句柄執行寫操作*
    use IO::Tee; 
    $tee = IO::Tee->new(">> debuglog.txt", \*STDOUT); 
    print $tee "an error ocurred on ".scalar(localtime)."\n";
    
    運行結果:an error ocurred on Fri Feb 23 21:44:20 2001 代碼討論:如果,由于種種原因你想要同時向兩個位置寫入同一個字符串,這和 UNIX 下的 tee 工具的用途一樣。即使你不是工作在 Unix 平臺上,Perl 也通過 Tee 模塊為你提供這個功能。Tee 模塊可以在 CPAN 下載,你應該把它安裝到 Perl 的 IO 庫文件夾中。Tee 模塊以 OOP 方式編寫,所以使用它之前你應該首先使用它的 new 方法來創建一個 Tee 對象,整個過程需要兩個參數,每個參數既可以是代表文件句柄的字符串,也可以是一個對已打開的文件句柄的引用。在上面的例子中,我們用一個字符串來代表一個以附加模式打開的文件句柄,它指向名為 debuglog.txt 的文件,另一個參數是系統內置的文件句柄 STDOUT,整個句柄是系統自動創建的,print 函數默認情況對它進行操作。為了得到一個文件句柄的引用我們需要對一個 typeglob 類型的數據使用反斜杠。Typeglob 可以代表任何已命名的某個變量,不論它是數組,散列還是標量等。使用 * 很有必要,因為文件句柄自己沒有前綴符號。new 操作符返回 Tee 類的一個實例對象,然后我們把整個實例賦給 $tee 標量?,F在,無論什么時候我們向 $tee 進行寫入操作,我們都同時向兩個位置進行寫操作。 *更多文件操作。。。* *從一個文件的完全路徑中找出它的名字*
    use File::Basename;
    $path = "/docs/sitecircus.com/html/tricks/trick.of.the.week.html";
    $basename = basename($path, ".html");
    print $basename;
    
    運行結果:trick.of.the.week 代碼討論:好了,成功了。問題是要找出文件的名字,要不帶任何路徑前綴,不帶任何擴展名。File::Basename 模塊可以使這很容易實現,我們只需要把文件的完全路徑還有要剔除的擴展名傳給它。上面的 path 變量是文件的完全路徑,注意文件分隔符是 /,這個字符很特殊,因為它是操作系統的保留字符。這里你不能在文件名里使用系統的分隔符。你應該知道當今流行的操作系統都使用自己獨特的文件分隔符:Unix使用 /,Windows 使用 \,Macintosh 使用 :(順便說一下,在 Windows 上的 Perl 腳本中,你既可以使用 \也可以使用 /作為文件分隔符,Perl 的解釋器能理解你的意思)。File::Basename,當然,能正確在完全路徑中找到文件名,不論時在什么系統下。 *改變文件的所有者*
    ($uid, $gid) = (getpwnam($username))[2,3]
        or die "$user not in passwd file";
    chown ($uid, $gid, $file)
        or warn "couldn't chown $file.";
    
    運行結果:無輸出代碼討論:有的時候,你可能知道一個用戶名,而你想用這個用戶名做些事,比如改變一個文件的所有者。但是不幸的是,Perl 的 chown 命令不能接受用戶名作為參數,但是可以接受一對數字:userid 和 groupid。雖然有這些不便之處,Perl 并沒有讓我們陷入困境,我們可以把用戶名作為 getpwnam 函數的參數,獲得一個數組,里面包含了用戶名對應的 userid 和 groupid,分別對應著數組里的第二和第三個元素。

    原文轉自:http://www.kjueaiud.com

    ...
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>