天天看點

Perl學習筆記-1

CPAN網站 ​​https://metacpan.org/​​

perl腳本語言時大小寫敏感的。

perl腳本的shebang[ʃɪˈbæŋ]行

which perl

#!/bin/perl
#!/usr/bin/perl      

分号的作用是分隔不同的perl語句,而不是斷行。

第一個樣例

#!/usr/bin/perl
@lines=`perldoc -u -fatan2`;
foreach(@lines){
    s/\w<[^>]+>/\U$1/g;
    print;
}      
  1. 數值

    perl中沒有整數,統一處理為雙精度型數。

    支援多種進制數。

    八進制數 0377

    十六進制數 0xff

    二進制數 0b11111111

    以上都為十進制數255

運算符:+,-,*,**,/,%

  1. 字元串

    perl中如果要使用中文,需

use utf8;      

單引号字元串直接量:\n按照普通字元解釋。

雙引号字元串直接量:解答轉義字元和多進制數。

幾個常用轉義字元

轉義字元 含義
\l 将下一個字母轉為小寫
\L 将後邊的所有字元轉為小寫,直到\E為止
\u 将下一個字母轉換為大寫
\U 将後邊的所有字元轉為大寫,直到\E為止
\Q 将後邊直到\E的 none word 字元加上反斜線轉義
\E 結束操作符

雙引号字元串可以完成變量字元内插。

字元串運算符

運算符 含義
. 句點 字元串連接配接
x 字元串重複。右邊的數字是重複的次數

Perl會根據需要自動完成數字和字元串的轉換。

  1. 内置警告
在代碼前部使用
use warnings;
或者在指令行帶-w參數
$ perl -w program
或者在shebang行
#!/bin/perl -w
輸出詳細告警資訊
use diagnostics;
或者在指令行
$ perl -Mdiagnostics ./program      
  1. 變量
  • 以$開頭
  • 變量名區分大小寫
  • 下劃線字母開頭
  • 變量名習慣全小寫,下劃線分割
  • 雙引号中可以對$變量完成内插
  1. 雙目運算符

    +=

    -=

    .=

  2. 輸出特殊字元

    chr() ascii數字轉字元

    ord() 字元轉ascii數字

    或者

"\x{03b1}\x{03c9}"      
  1. 比較運算符(與shell script相反)
  • 數值比較

    <,<=,==,>,>=,!=

  • 字元串比較

    lt,le,eq,ge,gt,ne

  1. 擷取使用者輸入
$line=<STDIN>
一般會使用chomp()去掉末尾的換行符
chomp($line=<STDIN>)      

注:函數可以加上括号也可以不加。隻要不改變表達式的含義()是可以省略的。

  1. 數組
$rocks[0]='bedroom';
最後一個元素的索引值是$#rocks。      

使用@(all)來引用整個數組,即數組的所有元素。

@rocks=qw/babe dfef sefe/;
@i=1..10;

@array=5..9;
$fred=pop(@array);  删除最後一個元素
push @array, 8;
push @array, 1..10;

删除開頭元素
$n=shift @array;

删除序号2及之後的元素(下标從0開始)
@removed=splice @array, 2;
從1開始删除2個元素
@removed=splice @array, 1, 2;

在指定位置插入元素
splice @array, 1, 0, qw(wilma)      
  1. 清單直接量
(1, 2, 3)
(1, 2, 3,)
("fred", 4.5)
()
(1..100)

quoted word
qw(fred barney betty wilma dino)
或
qw(
fred
barney
betty
wilma
dino)
()可以是其他字元,隻要配對就可以。主要是為了區分。      

清單指派

($fred, $barney, $dino) = ("flinsfga", "fwerc", undef);
交換兩個變量的值
($fred, $barney) = ($barney, $fred)      
  1. foreach控制結構
foreach $rock (qw/ bedrock slate lava /){
    print "One rock is $rock.\n"
}      

控制變量$rock不是清單元素的複制品,它就是清單元素本身。

  1. 預設變量$_
foreach (1..10){
    #預設使用$_作為控制變量
    print "I can count to $_!\n";
}      

當沒有告知perl使用哪個變量或數值時,perl會自動使用$_。

  1. reverse操作符
@fred=6..10;
@barney=reverse(@fred);
@wilma=reverse 6..10;
@fred=reverse @fred;      
  1. sort操作符

    隊清單排序。

  2. 使用each提取哈希鍵值對
@rocks=qw/ bedrock slate rubble granite /;
foreach $index (0..$#rocks){
    print "$index: $rocks[$index]\n";
}
或者
my @rocks=qw/ bedrock slate rubble granite /;
while(my($index,$value)=each @rocks){
    say "$index: $value";
}      
  1. 子程式
定義
sub{
    ....
    #最後一個表達式的運算結果作為傳回值
}
調用
&marine;      

子程式使用@_數組(私有化的,原值被壓棧儲存)接收參數清單。可以使用如下形式引用參數:

$_[0]        $_[1]      ......     
第一個參數   第二個參數    ......      

使用my定義私有變量

my($m,$n);
my不帶括号隻能定義一個變量。      

檢查參數長度

sub{
    if(@_!=2){
        ...
    }
}      

一個求輸入參數中的最大值的子程式例子

$maximum=&max(3, 5, 10, 4, 6);

sub{
    my($max_so_far)=shift @_;
    foreach(@_){
        if($_>$max_so_far){
            $max_so_far=$_;
        }
    }
    $max_so_far;
}      

return 控制子程式中途停止并傳回某個值。

使用state操作符來聲明變量,可以在子程式的多次調用期間保留變量的值,并将變量的作用域局限于子程式的内部。

  1. 輸入輸出
  • 鑽石操作符

    <> 如果給了指令行參數,就從指令行參數為檔案名的檔案中讀取;如果沒有給出指令行參數就從STDIN中讀取。鑽石操作符可以接收 | 過來的内容。

while(<>){  #将輸入讀入預設變量$_
    chomp;  #操作預設變量$_
    print "It was $_ that I saw!\n";
}      

指令行參數存放于@ARGV中。鑽石操作符會檢視@ARGV,然後決定用哪些檔案名。如果找到的是空清單,就會改用标準輸入流;否則就會使用@ARGV裡的檔案清單。

  1. 檔案句柄
  • 保留檔案句柄
保留檔案句柄 說明
STDIN 标準輸入
STDOUT 标準輸出
STDERR 标準出錯
DATA
ARGV
ARGVOUT
  • 打開檔案句柄
open CONFIG, 'dino';  隻讀打開
open CONFIG, '<dino'; 隻讀打開
open BEDROCK, '>gred'; 覆寫寫打開(無則建立)
open LOG, '>>logfile'; 追加寫打開(無則建立)

open CONFIG, '<', 'dino';
open BEDROCK, '>', $file_name;
open LOG, '>>', $logfile;
open LOG, '>>', &logfile_name();
open CONFIG, '<:encoding(UTF-8)', 'dino';
open BEDROCK, '>:encoding(UTF-8)', $file_name;
open BEDROCK, '<:crlf', $file_name; 讀取DOS回車換行結尾的檔案(讀入檔案的同時把DOS的CR-LF轉換為Unix風格的換行符)
open BEDROCK, '>:crlf', $file_name; 寫入DOS回車換行結尾的檔案

my $selected_output='my_output';
open LOG, "> $selected_output";  注意>後的空格可以防止覆寫寫      

可以把所有輸入和輸出句柄都改為UTF-8編碼

use open IN => ':encoding(UTF-8)';
use open OUT => ':encoding(UTF-8)';
或者
use open ':encoding(UTF-8)';      
  • 關閉檔案句柄
close BEDROCK;      
  • 用die處理緻命錯誤

    輸出指定資訊到STDERR,讓程式立即終止并傳回不為0的退出碼。

if(! open LOG, '>>', 'logfile'){
    die "Cannot create logfile: $!";
}      

預設變量“ $ ! ”存儲系統錯誤資訊。隻有在系統服務請求失敗後的瞬間,$!的值才會有用。

if(@ARGV<2){  #标量上下文的行為
    die "Not enough arguments\n";  #\n不讓perl帶上行号
}      
  • 自動檢測緻命錯誤

    編譯指令autodie會自動檢查緻命錯誤并調用die。

    注意:程式名儲存在特殊變量$0中

use autodie;      
  • 使用檔案句柄
if(! open PASSWD, "/etc/passwd"){
    die "How did you get logged in? ($!)";
}
while(<PASSWD>){
    chomp;
    ...
}      

輸出

print LOG "......\n";  #輸出到檔案句柄
printf STDERR "%d percent complete.\n", $done/$total *100;      

使用select改變預設的檔案輸出句柄

select BEDROCK;
print "...\n";      
select LOG;
$|=1;   #不要将LOG的内容保留在緩沖區
select STDOUT;
print LOG "...\n";      

将錯誤資訊儲存

if(! open STDERR,'>>',"/home/bee/.error.log"){
    die "Can't open error log for appand: $!";
}      

注,使用say将自動加上換行符。

say "Hello!";
say BEDROCK "Hello!";  #支援檔案句柄      

檔案句柄可以使用變量或者裸字。注意perl大小寫敏感。

裸字:STDOUT,LOG,MYFILE
變量:$file      

例子

open my $rock_fh, '<', 'rocks.txt' or die "Could not open rocks.txt: $!";
while(<$rock_fh>){
    chomp;
    ...
}
print $rock_fh "limestone\n";  #不要加逗号分割
close $rock_fh;      

輸出到句柄

print STDOUT; #将預設變量$_的内容輸出
print { $rock_fh };  #通過{}說明後邊接的是檔案句柄,且輸出$_中的内容。
print { $rocks[0] } "sandstone\n";      
  1. 哈希

    哈希就是鍵值對。鍵不能重複,但值可以重複。

$family_name{'fred'}='flintstone';
$family_name{$person}='babala';      

使用%來指帶整個哈希。哈希與清單可以互相轉換。

%some_hash=('foo',35,'bar',12.4,'wilam',23.4);
@any_array=%some_hash;
my %new_hash=%old_hash;      

鍵值對的存儲是無序的。

将”鍵-值“對變為”值-鍵“對。

my %inverse_hash=reverse %any_hash;
%ip_address= reverse %host_name;      

在清單中使用=>

my %last_name=(
    'fred' => 'flinestone',
    'dino' => undef,
    'arnet' => 'rubble',
    'betty' => 'ruble'
)

注:左邊鍵的引号可省。

my %last_name=(
    fred => 'flinestone',
    dino => undef,
    arnet => 'rubble',
    betty => 'ruble'
)      

如果鍵名是由字母,數字,下劃線組成的,并且不以數字開頭,就可以省略引号。這種字元序列稱為裸字(bareword)。

單個引用哈希時也可以使用裸字。

$score{'fred'}
可寫為
$score{fred}      

哈希函數

keys函數能傳回哈希的鍵清單。values函數能傳回對應的值清單。

my %hash=('a'=>1, 'b'=>2, 'c'=>3);
my @k=keys %hash;
my @v=values %hash;      

哈希的判斷上下文。

if(%hash){  #隻要哈希中有一個鍵值對,就傳回真
    print "That was a true value!\n";
}      

哈希的周遊

while(($key,$value)=each %hash){
    print "$key => $value\n";
}      
foreach $key (sort keys %hash){
    print "$key => $hash{$key}\n";
    ...
}      

哈希處理函數

函數名 含義
exists 是否存在某個鍵
delete 删除對應的鍵值對

讀取環境變量的哈希%ENV

$ENV{PATH}      
  1. 常用引号辨別
引号辨別 含義
q 是單引号
qq 是雙引号
qw 單詞清單引号
qr 正規表達式引号
qx