Perl 工作積累(不定期更新)

s1mba發表於2014-09-01
學會用 perl -c 檢查語法, perl -e 直接執行語句, perldoc 檢視文件 , CPAN 查詢 module ...
# 註釋; =pod ... =cut 多行註釋
特殊變數:
$$     Perl直譯器的程式ID
@ARGV  儲存命令列引數
@_    在子程式內,這個陣列變數包含傳遞給子程式的引數
$_           預設輸入
$/      當前輸入記錄分隔符,預設情況是新行
$!      根據上下文內容返回錯誤號或者錯誤串
$@    Perl直譯器從eval語句返回的錯誤訊息
$?      返回上一個外部命令的狀態

1)url 判斷是否合法:   /^(http:\/\/|https:\/\/)?((?:[A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+([A-Za-z0-9]+)[\/\?\:]?.*$/

如果想不用\ 去轉義 /, . , 等特殊字元,可以 /\Q$var\E/
在用 =~ 判斷字串包含時,需要注意是否包含空格等字元,特別是從檔案中讀出的時候,還要注意檔案中的空白行 $context =~ s/^\s*\n//mg;

 Perl Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
my $file = "blacklist.txt";
open(FILEIP, $file); 
while($var=<FILEIP>)
{       
    chomp $var;  # 去除換行
    if($var=~/^\s*(\S+)\s*$/)
    {
        $var=$1 # 去除左右空格
    }
    print "-$var-\n";  #加些邊界特殊字元列印,才能看出是否包含空格等字元
    if($site_name =~ /$var/)
    {       
        print "match it...\n";
        last;   
    }       
}


2)什麼時候需要轉義:1. 比如在"" 裡面還要使用",則\";  2. 一些特殊字元

3)資料庫亂碼問題:在指令碼中查詢的表和插入的表都要設定同樣的編碼如utf8($db_url->do(set names utf8)), 在secureCRT顯示時設定UTF-8,查詢資料庫顯示前set names utf8;

4)打log問題:如果log檔案沒許可權寫入,那會將log資訊輸出在標準輸出。secureCRT sz/rz 也會遇到目錄許可權的問題

5)倒資料不要全量重新倒,可以設定時間起始點甚至表自增id,從檔案讀出寫入;當tmmp表為空時,perl sql執行以下語句返回還是為真,需要再次判斷idmax的值是否為""
mysql> select max(id) idmax from tmmp;                                                            
+-------+
| idmax |
+-------+
|  NULL |
+-------+

6)perl 對型別還是要注意,如$url為字串,則如果判斷 $url == 0 很可能為真,字串比較儘量用 eq
    perl DBI 中的 my $ref = $sth->fetchrow_hashref();  $ref->{xxx} 返回的都是字串?

7) perl 的print $log "xxx" ;  syswrite $log, "xxxx";     perl中的printf很多字元列印有問題,最好是使用syswrite來列印資料

8) > or >> 如果檔案不存在都會建立,只是truncate or append的區別

9)sql 執行出錯,頁面出現很多亂碼,包括log檔案會有顯示不了的字元,往往是因為插入的引數包含亂碼,導致某些引號提早並上而執行出錯,有種解決辦法是隻取引數的有些長度欄位。可以用引數繫結的方式,搜尋 Binding Parameters to Statements。

10)當log檔案太大時,往往vim開啟會顯示為new file, 可以tail/head -n num file | more 來檢視部分內容

11)$db->quote($url) 這樣在插入sql時不用再對$url 加' ', 如果$url 內還有單引號會被轉義; sql 執行出錯很可能是引號提前閉合的問題
the single/double quotes are are properly escaped (ie. \') but the backslashes are not escaped.
如果字串中只是存在單一的 \(後面沒有跟 ", ', \, n, r, b 等),那麼db 將不插入任何字元。

12) mysql> pager less  多頁顯示

13)  select substring_index('xxx.xxx.xx.22', '.', -1)  // 得到22

14) perl中的雜湊賦值都是引用拷貝而非值拷貝

15) perl列印shell指令碼的結果資訊之前需要先chomp結果,否則列印出來的資訊不對

16)  取出url的字尾,如html, php等
    if ($url =~ /^(http:\/\/ | https:\/\/).*\/.*\.([^\/\.\?]+)/)
    {
          my $suffix = $2; 
    }

17) 從url中取出域名
      my @tmp = split(/:/, $url); my @tmp2= split(/\//, $tmp[1]);  my $domain = $tmp2[2];


18)解析Http 頭部資訊

 Perl Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
sub HttpHeadrParse#解析http頭部資訊
{
    my $header = shift;
#   $header =~s/\r\n/$~/g;
    my @element = split(/\r\n/,$header);

    my %hash;
    my $key ="";
    my $var ="";
    my @tmp="";
    foreach $var (@element)
    {
        if($var=~/POST./ or $var =~/GET./)
        {
            @tmp =split(/ /,$var);
            $hash{"Method"} = $tmp[0];
            $hash{"Cgi"} =$tmp[1];
#           print "method : $tmp[0] cgi: $tmp[1]\n";
            $hash{"Protocol"} =$tmp[2];
        }
        else
        {
            @tmp = split(/:/,$var);
            $hash{$tmp[0]}=$tmp[1];
            if($tmp[0eq "Host")
            {
                if($tmp[2eq "")
                {
                    $hash["Port"] = "80";
                }
                else
                {
                    $hash["Port"] = $tmp[2];
                }
            }

        }
    }

    return %hash;
}

19)去除左右空格

 Perl Code 
1
2
3
4
5
6
7
sub trim
{
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

20)根據url, get, post 做md5 去重

 Perl Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#輸入name,value字串,name界定符;返回唯一的name列表
sub get_name{
    my $param = shift;
    my $delim = shift;
    return '' if !defined($param) ||  $param eq '';
    my @name_value = split("$delim", $param);
    my %hash_name_value = ();
    for(my $i = 0; $i<= $#name_value; $i++){
        my $name = '';
        my $value = '';
        if($name_value[$i] =~ /([^=]+)=(.*)/){
            $name = $1;
            $value = $2;
        }
        if($name =~ /[.\d]{10,50}|1\d{9,9}$/){ #去除隨機數name
            next;
        }
        $hash_name_value{"$name"} = $value;
    }
    my @names = sort keys %hash_name_value;
    my $names_str = join("$delim",@names);
    return $names_str;
}

#計算uniquemd5
sub uniquemd5{
    my ($url, $params, $query_get, $query_post) = @_;
    my $uniquemd5_str = $url;
    my $port = 0;
    my $q_get_name = '';
    my $q_post_name = '';
    my $p_name = '';
    $q_get_name = get_name($query_get, '&');
    $q_post_name = get_name($query_post, '&');
    $p_name = get_name($params, ';');
    
    if($url =~ m/(?:http|https):\/\/[^:\/;?#]+(?::([0-9]+))?/){
        $port = $1;
    }
    if(defined $port && 80 == $port){
        $uniquemd5_str =~ s/:[0-9]+//;
    }
    
    $uniquemd5_str .= ",$p_name,$q_get_name,$q_post_name";
    my $md5 = Digest::MD5->new;
    my $uniquemd5 = $md5->add($uniquemd5_str)->hexdigest;
    return $uniquemd5;

}

21)一次性讀取整個檔案內容

open my $fh, '<', 'file.txt' or die $!; #系統或庫呼叫fail時會設定$!
my $content = do { local $/; <$fh> };


相關文章