当前位置:Linux教程 - Linux - 善用 Perl Date Structure 和 reference

善用 Perl Date Structure 和 reference



         很多初學 Perl script 的初用者,都不喜歡從 Data Structure 和 reference 中思考和解決問題,這可能是因為他們不習慣在編寫程式時先考慮資料和資料結構。但是很多時候從這方面入手會更容易解決問題。舉個例子吧!


    今天收到我學生的來信,他有一個檔案是存放使用者資料,這檔案名稱為 cusers.map ,而這檔案的內容如下。

    winnie.chan=Winnie Chan=
    tom.chow=Tom Chow=
    frankie.chow=Frankie Chow=

    這檔案的意義就是說當在資料中如果遇上 Frankie Chow 就把它轉換成 frankie.chow ,另外當遇上 Peter wong 就把它轉換成 peter.wong 。

    另外有一檔案名為 test.ldif ,讀者可以先把它看成一個普通的文字檔案。

    dn: uid=Frankie Chow,ou=users,ou=samba,dc=godclick,dc=net
    uid: Frankie Chow
    sambaSID: S-1-5-21-2093837416-124xxxxxxxxxxxxxxxxxxxxxxxx70-1872
    sambaPrimaryGroupSID:
    S-1-5-21-2093837416-124xxxxxxxxxxxxxxxxxxxxxxxxxxxxx70-513
    displayName: Frankie Chow
    sambaLogonTime: 1079690765
    sambaLogoffTime: 2147483647
    sambaKickoffTime: 2147483647
    sambaPwdCanChange: 0
    sambaPwdMustChange: 2147483647
    sambaLMPassword: 29B9xxxxxxxxxGHTHC
    sambaNTPassword: 96B9xxxxxxxxxTHHDA
    sambaPwdLastSet: 1064457577
    sambaAcctFlags: [UX ]
    objectClass: sambaSamAccount
    objectClass: account

    dn: uid=Tom Chan,ou=users,ou=samba,dc=godclick,dc=net
    uid: Tom Chan
    sambaSID: S-1-5-21-2093837416-124xxxxxxx70-1682
    sambaPrimaryGroupSID: S-1-5-21-2093837416-124xxxxxx70-513
    ...

    現在把 test.ldif 中所遇見的任何串字倚 cuser.map 來轉換。很多時初學 Perl 的學生就會先想把 cuser.map 打開,然後再打開 test.ldif ,然後比較轉換。其實這種思考方式就是沒有善用 perl 中的資料結構功能。

    其實可以用以下的方式來重新思考這問題。可以先建立一資料結構 < arrayref/hashref >,然後把 cuser.map 內的各筆資料放入,那只需要使用一個簡單的 foreach 就可以把 test.ldif 的資料來作轉換了。

    這是筆者的 perl script

    ------------------------------------------------------------------------

    #!/usr/bin/perl -w

    sub cNameMap {

    # Create a Data Structure for storage cuser.map
    # $cname = [
    # {
    # source => "Frankie Chow",
    # target => "frankie.chow"
    # },
    # ...
    # ];

    my $cname = [];

    open $datafile, "

    while (<$datafile>) {

    @usermapdata = split("=",$_);
    push (@$cname, {
    source => $usermapdata[1],
    target => $usermapdata[0]
    } );
    };

    return $cname ;
    }

    $cnamemap = &cNameMap ;
    CHANGEFILE: {

    open $sourcefile, "<test.ldif"; while ($line = <$sourcefile>) { foreach (@$cnamemap) { $line =~ s/$_->{source}/$_->{target}/;

    };
    print $line;
    };
    };

    __END__




    发布人:raink 来自:LinuxHall.org