perl - Practical Extraction and Report Language,Perl有很多命令行參數(shù),通過它可以讓你的程序更簡(jiǎn)練,并且可以寫出很多只有一行命令的perl。在這篇文章里我們來了解一些常用的命令行參數(shù)。
命令行調(diào)用
復(fù)制代碼 代碼如下:
perl [ -sTtuUWX ]
[ -hv ] [ -V[:configvar] ]
[ -cw ] [ -d[t][:debugger] ] [ -D[number/list] ]
[ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ]
[ -Idir ] [ -m[-]module ] [ -M[-]'module...' ] [ -f ]
[ -C [number/list] ]
[ -P ]
[ -S ]
[ -x[dir] ]
[ -i[extension] ]
[ [-e|-E] 'command' ] [ -- ] [ programfile ] [ argument ]...
[開關(guān)項(xiàng)描述]
-0
規(guī)定記錄分隔符。
-0數(shù)字>
(用8進(jìn)制表示)指定記錄分隔符($/變量),默認(rèn)為換行
-00
段落模式,即以連續(xù)換行為分隔符
-0777
禁用分隔符,即將整個(gè)文件作為一個(gè)記錄
-a
與 -n 或者 -p 一起使用,負(fù)責(zé)打開自動(dòng)拆分模式,用于對(duì)空白字符進(jìn)行隱式拆分,用空格分隔$_并保存到@F中,相當(dāng)于@F=split ''。分隔符可以使用-F參數(shù)指定例如:
復(fù)制代碼 代碼如下:
date | perl -ane 'print "$F[0]\n"';
-c
只檢查 Perl 腳本語法,而不執(zhí)行腳本。
-d
對(duì)腳本打開 Perl調(diào)試器。
-D
設(shè)置 Perl 的調(diào)試標(biāo)記(請(qǐng)先檢查 Perl 的安裝情況,確保已經(jīng)安裝了調(diào)試器),若要觀察 Perl 是如何執(zhí)行腳本的,可使用 -D14。
-e command
用于再命令行而不是在腳本中執(zhí)行 Perl 命令。
-F pattern
規(guī)定拆分輸入行時(shí)使用的模式。模式是位于斜杠、單引號(hào)或雙引號(hào)之間的正則表達(dá)式。例如,-F/:+/ 表示在一個(gè)或多個(gè)冒號(hào)上拆分輸入行,如果 -a 仍然起作用的話,則打開它。
-h
打印 Perl 的命令選項(xiàng)列表。
-i extension
在使用 > 循環(huán)遍歷文件時(shí)啟用原位編輯模式。 如果沒有規(guī)定擴(kuò)展名的話,則原位修改各行內(nèi)容,否則使用擴(kuò)展名來修改輸入文件名(以便充當(dāng)備份文件),并使用原位編輯的原文件名創(chuàng)建輸出文件。 這也是所有 print 語句選擇的文件句柄。
-I directory
與 -P選項(xiàng)一起使用,負(fù)責(zé)告訴 C 預(yù)處理程序查找包含的文件,其默認(rèn)目錄包括 /usr/included、/usr/lib/perl 以及當(dāng)前目錄。
-1 digits
啟用自動(dòng)行結(jié)束處理。如果使用了 -n 或者 -p 選項(xiàng),則去掉終止符。把位數(shù)(八進(jìn)制) 賦值給 $\ ,并將行終止符添加到 print 語句中。如果沒有規(guī)定位數(shù)的話,則將 $\ 設(shè)置為 $/ 的當(dāng)前值。
-l
對(duì)輸入內(nèi)容自動(dòng)chomp,對(duì)輸出內(nèi)容自動(dòng)添加換行。使用 -l 有兩個(gè)效果,第一自動(dòng) chomp 輸入分隔號(hào),第二 把$/ 值付給 $\ (這樣 print 的時(shí)候就會(huì)自動(dòng)在末尾加 \n)
復(fù)制代碼 代碼如下:
-m [-] module
-M [-] module
-M [-] module'
-[mM] module =
arg [,arg]..
-m module
在執(zhí)行 Perl 腳本之前執(zhí)行 use 方法。
-M module
再執(zhí)行 Perl 腳本之前執(zhí)行 use 方法。如果添加附加的文本,則可使用引號(hào)。方括號(hào)中的短橫線表示把 use 指令替換為 no。
-n
使 Perl 隱式地循環(huán)遍歷指定的文件,并只打印規(guī)定的行。自動(dòng)循環(huán),相當(dāng)于 while(>) { 腳本; }
-p
使 Perl 隱式地循環(huán)遍歷指定的文件,同時(shí)打印所有的行。自動(dòng)循環(huán)+自動(dòng)輸出,相當(dāng)于 while(>) { 腳本; print; }
-P
使要運(yùn)行的腳本在 Perl 編譯之前通過 C 預(yù)處理程序。
-s
再腳本名之后、文件名參數(shù)之前啟用開關(guān)項(xiàng)解析,并從@ARGV 數(shù)組中刪除所有找到的開關(guān)項(xiàng)。將開關(guān)項(xiàng)設(shè)置為同名的標(biāo)量型變量,并將標(biāo)量賦值為 1 。例如,-abc 在腳本中將轉(zhuǎn)換為 $abc。
-S
如果不支持 #!/usr/bin/perl 行,則讓 Perl 在 PATH 環(huán)境變量中搜索腳本。
-T
強(qiáng)制打開“污染“ 檢查,用于測(cè)試腳本,一般只用在 setuid 或 setgid 程序上。推薦自行檢查 CGI 腳本。
-u
編譯后產(chǎn)生腳本的核心轉(zhuǎn)儲(chǔ)(基于 UNIX 系統(tǒng))。
-U
允許 Perl 執(zhí)行不安全的操作,如果是超級(jí)用戶的話,則斷開目錄鏈接。
-v
打印 Perl 的版本信息。
-V
打印最重要的 Perl 配置項(xiàng)和數(shù)組 @INC 中當(dāng)前值的匯總。
-V:NAME
打印 NAME 的值,其中 NAME 是配置變量。
-w
打印警告信息,包括錯(cuò)誤使用保留字、文件句柄、子例程等情況。
-W
啟用所有警告,而不論是否已經(jīng)用 no warnings 關(guān)閉了本地警告。
-x directory
忽略 #!/usr/bin/perl 行之前的任何文本。如果將目錄名當(dāng)作 -x 開關(guān)的參數(shù),則 Perl 會(huì)在開始執(zhí)行腳本之前自動(dòng)切換到該目錄。
-X
關(guān)閉所有警告。
每一行將缺省保存在 $_,-p 和 -n 一樣,但是還會(huì)打印 $_ 的內(nèi)容。
請(qǐng)注意:-p 開關(guān)和 -n 開關(guān)的使用。當(dāng)您想顯式打印數(shù)據(jù)時(shí),使用 -n 開關(guān)。-p 開關(guān)隱式地將 print $_ 語句插入到 -n 開關(guān)所產(chǎn)生的循環(huán)中。因此,-p 開關(guān)更適用于對(duì)文件進(jìn)行的完全處理,而 -n 開關(guān)更適用于選擇性文件處理,這樣的處理只需打印特定數(shù)據(jù)。
安全網(wǎng)參數(shù)
有三個(gè)參數(shù)我認(rèn)為可以起到“安全網(wǎng)”的作用,因?yàn)樗鼈兛梢宰屇惚苊夥稿e(cuò),特別是當(dāng)你在使用 Perl 嘗試一些特別聰明(或這愚蠢)的想法時(shí),錯(cuò)誤難免會(huì)發(fā)生。有經(jīng)驗(yàn)的 Perl 程序員常常使用這三個(gè)參數(shù)來提前找到錯(cuò)誤所在。
-c 是第一個(gè)。這個(gè)參數(shù)編譯 Perl 程序但并不真正運(yùn)行它,由此檢查所有語法錯(cuò)誤,每次修改 perl 程序之后我都會(huì)立刻使用它來找到任何語法錯(cuò)誤。
復(fù)制代碼 代碼如下:
$ perl -c program.pl
這保證了程序依然可以編譯。很顯然,當(dāng)你輸入一小段代碼之后立即進(jìn)行檢查,比起一下子輸入幾百行代碼然后開始 debug 要容易很多。
-W 是第二個(gè)參數(shù)。它會(huì)提示你任何潛在的bug。Perl 5.6.0 之后的版本已經(jīng)用 use warnings; 替換了-w。你應(yīng)該使用 use warnings 因?yàn)樗?-w 更靈活。
-T 是第三個(gè)參數(shù)。它讓 perl 出于了 taint 模式中。在這個(gè)模式里,Perl 會(huì)質(zhì)疑任何程序外傳來的數(shù)據(jù)。例如從命令行讀取,外部文件里讀取或是 CGI 程序里傳來的數(shù)據(jù)。這些數(shù)據(jù)在 -T 模式里都會(huì)被 Tainted(污染),Tainted 數(shù)據(jù)不可以被用來和外部交互。例如使用在 system 調(diào)用和用作 open 的文件名,關(guān)于什么數(shù)據(jù)會(huì)被Tainted,請(qǐng)參閱perlsec 文檔,那里有一個(gè)完整的列表。
要想使用 Tainted 的數(shù)據(jù)就必須 untaint這個(gè)數(shù)據(jù)。untaint是通過正則表達(dá)式來實(shí)現(xiàn)的,關(guān)于 taint 本身的內(nèi)容足夠?qū)懸黄獑为?dú)的文章,所以這里我不會(huì)太多的講述 taint 模式。如果你要編寫的程序(例如 CGI 程序)需要從從用戶那里接受不可知的輸入,我推薦使有 taint 模式。
還有一個(gè)值得一提的參數(shù)是 -d,它將讓 Perl 處于 Debugger 模式。這個(gè)話題內(nèi)容非常多,我推薦閱讀文檔 ‘perldoc perldebug'或 Richard Foley 的 Perl Debugger Pocket Reference 一書.
使用模塊
下面的幾個(gè) Perl 參數(shù)可以讓短小的 Perl 程序很容易的在命令行上運(yùn)行,-e 可以讓 Perl代碼在命令行上被編譯器直接執(zhí)行。例如,我們可以直接在命令行上運(yùn)行“Hello World” 程序而不用把它寫稱 Perl 程序。
復(fù)制代碼 代碼如下:
$ perl -e 'print "Hello World\n"'
多個(gè) -e 也可以同時(shí)使用,運(yùn)行順序根據(jù)它出現(xiàn)的位置。
復(fù)制代碼 代碼如下:
$ perl -e 'print "Hello ";' -e 'print "World\n"'
象所有的 Perl 程序一樣,只有程序的最后一行不需要以 ; 結(jié)尾,你也可以用 -e 來引用模塊,但 -M 讓它變得更容易。
復(fù)制代碼 代碼如下:
$ perl -MLWP::Simple -e 'print head "http://www.example.com"'
-M模塊名和use 模塊名一樣。有些模塊有默認(rèn)的模塊導(dǎo)入,如果你不想導(dǎo)入它們,你可以使用-m。-m模塊名和 use module() 一樣,關(guān)閉了默認(rèn)的導(dǎo)入。例如下面這個(gè)例子,因?yàn)?head 函數(shù)是默認(rèn)導(dǎo)入,而使用-m 時(shí)就不會(huì)執(zhí)行,結(jié)果是沒有輸出。
復(fù)制代碼 代碼如下:
$ perl -mLWP::Simple -e 'print head "http://www.example.com"'
-m 和 -M 有很多方便的語法來幫助你使用它們,你可以在 = 后面列出對(duì) use 的各種參數(shù)。
復(fù)制代碼 代碼如下:
$ perl -MCGI=:standard -e 'print header'
在這里,CGI.pm 的 :standard 被引入,header 函數(shù)因此可以使用。要引入多個(gè)參數(shù)可以通過使用引號(hào)和逗號(hào)。
復(fù)制代碼 代碼如下:
$ perl -MCGI='header,start_html' -e 'print header,start_html'
這里我們引入了 header 和 start_html 函數(shù)。
Implicit Loops
-n 和 -p 增加了循環(huán)的功能,使你可以一行一行來處理文件。
復(fù)制代碼 代碼如下:
$ perl -n -e 'some code' file1
這與下面的程序一樣.
LINE:
復(fù)制代碼 代碼如下:
while () {
# your code goes here
}
注意:打開命令行里的文件,一行行的讀取,每一行將缺省保存在 $_。
復(fù)制代碼 代碼如下:
$ perl -n -e 'print "$. - $_"' file
上面的這一行可以寫成 LINE: while () { print ”$. – $_” } 輸出當(dāng)前行數(shù) $. 和當(dāng)前行 $_,-p可以讓上面的程序變得更容易,-p 會(huì)輸出 $_ 的內(nèi)容,就像這樣:
復(fù)制代碼 代碼如下:
while () {
# your code goes here
} continue {
print or die "-p destination: $!\n";
}
continue 在這里保證 print 在每次循環(huán)都會(huì)被調(diào)用。使用 -p,我們的打印行數(shù)程序可以改為
復(fù)制代碼 代碼如下:
$ perl -p -e '$_ = "$. - $_"' filename
這種情況下我們就不需要要明確地調(diào)用 print 函數(shù)了,因?yàn)?-p 選項(xiàng)已經(jīng)調(diào)用了它。注意,LINE: 標(biāo)簽可以讓我們直接跳到下一個(gè)輸入記錄,而不管你進(jìn)入了多少層循環(huán),使用 next LINE。
復(fù)制代碼 代碼如下:
$ perl -n -e 'next LINE unless /pattern/; print $_'
當(dāng)然,也可以這樣寫:
復(fù)制代碼 代碼如下:
$ perl -n -e 'print unless /pattern/'
在更復(fù)雜的情況里,next LINE可以讓你的代碼更容易理解。如果想在循環(huán)的前后做些處理,可以使用 BEGIN或END block,下面的這一行代碼可以計(jì)算 text 文件里的字?jǐn)?shù):
復(fù)制代碼 代碼如下:
$ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt
每一行所有匹配的字放入數(shù)組 @w,然后把 @w 的元素?cái)?shù)目遞加到$t,END block 里的 print 最后輸出文件總字?jǐn)?shù)。
還有兩個(gè)參數(shù)可以讓這個(gè)程序變得更簡(jiǎn)單,-a 打開自動(dòng)分離 (split) 模式,空格是缺省的分離號(hào),輸入根據(jù)分離號(hào)被分離然后放入缺省數(shù)組 @F。由此,我們可以把上面的程序改寫為:
復(fù)制代碼 代碼如下:
$ perl -ane 'END {print $x} $x += @F' file.txt
你也可以通過 -F 把缺省的分離號(hào)改為你想要的.例如把分離號(hào)定為非字符:
復(fù)制代碼 代碼如下:
$ perl -F'\W' -ane 'END {print $x} $x += @F' file.txt
下面通過 Unix password 文件來介紹一個(gè)復(fù)雜的例子。Unix password 是文本文件,每一行是一個(gè)用戶記錄,由冒號(hào) ':'分離。第6列是用戶的登錄 shell 路徑,我們可以得出每一個(gè)不同 shell 路徑被多少個(gè)用戶使用:
復(fù)制代碼 代碼如下:
$ perl -F':' -ane 'chomp($F[6]); $s{$F[6]}++; END{print"$_:$s{$_}n" for keys %s}' /etc/passwd
$ perl -F':' -alne '$s{$F[6]}++;' -e 'END { foreach (keys %s){chomp($_);print "$_ \: $s{$_}"} }' /etc/passwd
有如下輸出:
復(fù)制代碼 代碼如下:
/usr/sbin/nologin : 3
/bin/sh : 18
/bin/sync : 1
/bin/bash : 2
/bin/false : 9
數(shù)據(jù)分隔符
我以前的文章里提到過 $/ 和 $\—輸入,輸出分隔號(hào)。$/ 用來分隔從文件句柄里讀出的數(shù)據(jù),缺省 $/ 分隔號(hào)是 \n,這樣每次從文件句柄里就會(huì)一行行的讀取。$\ 缺省是空字符,用來自動(dòng)加到要 print 的數(shù)據(jù)尾端。這就是為什么很多時(shí)候 print 都要在末尾加上 \n,$/ 和 $\ 可與 -n -p 一起使用。在命令行上相對(duì)應(yīng)為 -0 (零) 和 -l (這是 L)。-0 后面可以跟一個(gè)16 進(jìn)制或8進(jìn)制數(shù)值,這個(gè)值用來賦給 $/。-00 打開段落模式,-0777 打開slurp 模式(即可以一次把整個(gè)文件讀入),這與把 $/ 設(shè)為空字符和 undef 一樣效果。
單獨(dú)使用 -l 有兩個(gè)效果,第一自動(dòng) chomp 輸入分隔號(hào),第二 把$/ 值付給 $\ (這樣 print 的時(shí)候就會(huì)自動(dòng)在末尾加 \n)我個(gè)人常常使用 -l 參數(shù),用來給每一個(gè)輸出加 \n,例如:
復(fù)制代碼 代碼如下:
$ perl -le 'print "Hello World"'
原位編輯
使用已有的參數(shù)我們可以寫出很有效的命令行程序. 常見的Unix I/O 重定向:
復(fù)制代碼 代碼如下:
$ perl -pe 'some code' output.txt
這個(gè)程序從 input.txt 讀取數(shù)據(jù),然后做一些處理再輸出到 output.txt. 你當(dāng)然也可以把輸出重定向到同一個(gè)文件里。上面的程序可以通過 -i 參數(shù)做的更簡(jiǎn)單些。-i 把源文件更名然后從這個(gè)更名的源文件里讀取,最后把處理后的數(shù)據(jù)寫入源文件。如果 -i 后跟有其他字符串,這個(gè)字符串與源文件名合成后來生成一個(gè)新的文件名,此文件會(huì)被用來儲(chǔ)存原始文件以免被 -i 參數(shù)覆蓋。
這個(gè)例子把所有php字符替換為perl :
復(fù)制代碼 代碼如下:
$ perl -i -pe 's/\bPHP\b/Perl/g' file.txt
程序讀取文件的每一行,然后替換字符,處理后的數(shù)據(jù)重新寫入(即覆蓋) 源文件. 如果不想覆蓋源文件,可以使用$perl -i.bak -
復(fù)制代碼 代碼如下:
pe 's/\bPHP\b/Perl/g' file.txt
這里處理過的數(shù)據(jù)寫入 file.txt ,file.txt.bak 是源文件的備份。
打開Perl的taint模式
1、該程序的輸入數(shù)據(jù)來自外部數(shù)據(jù)源。
2、該程序所調(diào)用sub-shell或者函數(shù)影響到該程序之外其它東西。
你可以用“-T”開關(guān)來打開Perl的taint模式。當(dāng)打開taint模式時(shí),Perl就會(huì)進(jìn)行執(zhí)行檢查以確保你的數(shù)據(jù)未被taint,如果不安全的使用了被taint的數(shù)據(jù),就會(huì)發(fā)出嚴(yán)重錯(cuò)誤。為了使你的數(shù)據(jù)不被taint,執(zhí)行正則表達(dá)式來匹配數(shù)據(jù)并提取匹配部分。這樣你就必須描述出你所期望的數(shù)據(jù)的內(nèi)容以及格式,并只接受符合這一要求的數(shù)據(jù)。
例如,假設(shè)你期望收到一個(gè)單詞字符(word characters,即字母數(shù)字以及下劃線),那么下面的代碼通過一個(gè)正則表達(dá)式(它只通過全部由單詞字符組成字符串)會(huì)“蒸餾出”你的數(shù)據(jù)來:
復(fù)制代碼 代碼如下:
if ($data =~ /^(\w+)$/) {
$data = $1;
} else {
die ”Error: tainted data found: $data\n”;
}
Perl命令行調(diào)試
缺省的Perl調(diào)試器就是perl解釋器本身,另外還有圖形界面的調(diào)試器。圖形界面的調(diào)試器推薦ptkdb,這里不再進(jìn)行介紹,下載安裝以后用兩次便會(huì)。所以這里主要介紹一下缺省的命令行調(diào)試器的用法,一般的調(diào)試,用下面這些命令已經(jīng)足夠了,這些命令說明也來自網(wǎng)上整理而成。
用 -d 命令行選項(xiàng)啟動(dòng)Perl解釋器,例如:
perl -d test.pl 即進(jìn)入Perl調(diào)試器的交互界面。
調(diào)試命令列表如下:(所有命令都在調(diào)試提示符下頂格輸入,命令大小寫有關(guān))
h:顯示調(diào)試器的幫助信息。
|h:以分頁形式顯示調(diào)試器的幫助信息。
h h:顯示一個(gè)壓縮的幫助信息。
h 調(diào)試命令:顯示某個(gè)調(diào)試命令的幫助。
p 表達(dá)式:顯示變量或表達(dá)式的值,不顯示復(fù)雜變量嵌入的結(jié)構(gòu)和數(shù)據(jù)。
x 表達(dá)式:顯示變量或表達(dá)式的值,對(duì)較為復(fù)雜的變量,以一種可讀形式顯示嵌入的結(jié)構(gòu)和數(shù)據(jù)。
V 包名 變量名列表:顯示指定包內(nèi)的所有(或部分)變量的值。(缺省的包名為 main)
X 變量名列表:顯示當(dāng)前包內(nèi)所有(或部分)變量的值。
注:V、X命令中的變量名列表以空格分隔且變量名前應(yīng)去掉$、@或%。
T:程序的調(diào)用棧回退一級(jí)。
s 表達(dá)式:?jiǎn)尾綀?zhí)行,進(jìn)入子函數(shù)。(step into)如果提供一個(gè)表達(dá)式并且表達(dá)式中包括函數(shù)調(diào)用,則單步進(jìn)入該函數(shù)內(nèi)。
n 表達(dá)式:?jiǎn)尾綀?zhí)行,越過子函數(shù)。(step over)
c 行號(hào)/函數(shù)名:執(zhí)行到某一行或某一個(gè)函數(shù)。
l:顯示未執(zhí)行的一窗(一屏)文件內(nèi)容。
l min-max:顯示第min到第max行的文件內(nèi)容。
l 行號(hào):顯示指定行的內(nèi)容。
l 函數(shù)名:顯示指定函數(shù)的一窗(一屏)文件內(nèi)容。
w 行號(hào):顯示某行周圍一窗(一屏)文件內(nèi)容。
f 文件名:切換到另一個(gè)文件。
/模式:在當(dāng)前文件中向前(文件尾)查找匹配的字符串。
?模式:在當(dāng)前文件中向后(文件頭)查找匹配的字符串。
L:顯示所有斷點(diǎn)和附加操作。
S 模式:顯示匹配(或不匹配,在模式前加!)的函數(shù)名。
t:切換跟蹤模式。
t 表達(dá)式:跟蹤執(zhí)行表達(dá)式過程。
b 行號(hào) 條件:在某一行設(shè)置一個(gè)斷點(diǎn),當(dāng)程序執(zhí)行到該行并且條件滿足時(shí),產(chǎn)生中斷。
b 函數(shù)名 條件:在某函數(shù)上設(shè)置一個(gè)斷點(diǎn),當(dāng)程序執(zhí)行到該函數(shù)并且條件滿足時(shí),產(chǎn)生中斷。
b load 文件名:在某個(gè)文件的第一個(gè)可執(zhí)行語句上設(shè)置一個(gè)斷點(diǎn)。
d 行號(hào):刪除某一行的斷點(diǎn)。
D:刪除所有斷點(diǎn)。
a 行號(hào) 命令:給程序的某一行加一個(gè)附加操作。在執(zhí)行該行語句前先執(zhí)行附加的操作。
A:刪除所有已安裝的附加操作。
W 表達(dá)式:增加一個(gè)監(jiān)視項(xiàng)。
W:刪除所有監(jiān)視項(xiàng)。
O 選項(xiàng)名?:查詢調(diào)試器可選項(xiàng)的值。
O 選項(xiàng)名=選項(xiàng)值:設(shè)置調(diào)試器可選項(xiàng)的值。
lt Perl語句:設(shè)置一個(gè)操作顯示調(diào)試提示符前執(zhí)行的操作。
ltlt Perl語句:增加一個(gè)顯示調(diào)試提示符前執(zhí)行的操作。
gt Perl語句:設(shè)置一個(gè)離開調(diào)試提示符(轉(zhuǎn)入運(yùn)行態(tài))時(shí)執(zhí)行的操作。
gtgt Perl語句:增加一個(gè)離開調(diào)試提示符(轉(zhuǎn)入運(yùn)行態(tài))時(shí)執(zhí)行的操作。
{ 調(diào)試命令:設(shè)置一個(gè)操作顯示調(diào)試提示符前執(zhí)行的操作。
{{ 調(diào)試命令:設(shè)置一個(gè)操作顯示調(diào)試提示符前執(zhí)行的操作。
注:上述Perl語句和調(diào)試命令均可輸入多行,行尾以\轉(zhuǎn)義。
!number:重新執(zhí)行以前第number次執(zhí)行的調(diào)試命令。
!-number:重新執(zhí)行現(xiàn)在以前number次執(zhí)行的調(diào)試命令。
!模式:重新執(zhí)行以前執(zhí)行過的與模式匹配的調(diào)試命令。
!!命令:不退出調(diào)試器執(zhí)行一個(gè)shell命令。
H-number:顯示以前執(zhí)行的number條調(diào)試命令。如果省略number,則顯示所有執(zhí)行過的調(diào)試命令。
R:重新啟動(dòng)正在調(diào)試的程序。
q或^D:退出調(diào)試器。
|調(diào)試命令:將調(diào)試命令的輸出分頁顯示。
||調(diào)試命令:類似|調(diào)試命令,適于有大量輸出的調(diào)試命令,例如:|V main。
= 別名 值:給某個(gè)調(diào)試命令一個(gè)別名,例如:= quit q。
所有未識(shí)別的命令:當(dāng)作插入的一條Perl語句執(zhí)行。(使用eval)
Perl調(diào)試器的功能還有很多,可以設(shè)置很多選項(xiàng)來定制調(diào)試器的環(huán)境,它本身也是用Perl開發(fā)的,并且Perl發(fā)布中還有接口讓你能開發(fā)其它的Perl調(diào)試器。如果要用Perl開發(fā)大的項(xiàng)目,有必要詳細(xì)了解這些細(xì)節(jié)。使用調(diào)試器和設(shè)置調(diào)試器選項(xiàng)的例子請(qǐng)參考Perl發(fā)布中關(guān)于perldebug的文檔。
更多信息
Perl有大量的命令行參數(shù),這篇文章只是列舉了最有用的一小部分,更詳細(xì)的信息請(qǐng)參考“perlrun” 文檔。
命令行的運(yùn)用
用perl做命令行的一些簡(jiǎn)單的介紹,來替代sed、awk之類的軟件。
Perl作為命令行實(shí)用程序,可以度參考ibm的這篇文章。作者提到的很重要的一點(diǎn)是:有經(jīng)驗(yàn)的程序員不應(yīng)回避快速而又難看的解決方案。
Perl單行命令示例
我們先看看perl如何接收用戶的參數(shù)。如下,Dumper模塊不用理會(huì),只是它會(huì)給數(shù)據(jù)結(jié)構(gòu)打印出來,shell給接收到的參數(shù)都放到了@ARGV這個(gè)數(shù)組。
復(fù)制代碼 代碼如下:
perl -MData::Dumper -e 'print Dumper \@ARGV' a b -w
$VAR1 = [
'a',
'b',
'-w'
];
如上,perl可以直接接收到shell命令行的參數(shù)?!?e”后的任何內(nèi)容并將它當(dāng)作腳本來運(yùn)行?!?M”參數(shù)表示獲取其后的任何內(nèi)容并將該內(nèi)容作為模塊導(dǎo)入,類似于正規(guī)腳本中的“use ModuleName”。我們可以看到象所有的 Perl 程序一樣,只有程序的最后一行不需要以 ; 結(jié)尾。
注:-e在單行命令中非常的重要,做單行命令時(shí)一定要加入在使用perl的單行命令時(shí)要注意使用”,不要使用"",其實(shí)sed和awk也是一樣,當(dāng)然這只是一個(gè)建議,看下面的例子就能明白:
復(fù)制代碼 代碼如下:
perl -e 'print "$$\n"'
5719
'$$'在perl中表示當(dāng)前的pid,如果使用的是單引號(hào),其中還可以放雙引號(hào),還有變量,重要的是,這些變量不用擔(dān)心被shell轉(zhuǎn)義。
復(fù)制代碼 代碼如下:
perl -pi -e 's/aaa/bbb/' filename
修改當(dāng)前file文件中的文件,不生成中間文件,速度很快.記住 -i 開關(guān),因?yàn)樗屇阍鼐庉嬑募?/p>
復(fù)制代碼 代碼如下:
perl -ne 'print if /^int/' filename
象grep一樣過濾文件中需要的內(nèi)容。這個(gè)地方,使用了-n,所以一次是做一行的操作,直到整個(gè)文件讀完。另外,在管道時(shí),-n也會(huì)一樣,來遍歷管道送過來的內(nèi)容。
復(fù)制代碼 代碼如下:
perl -n -e 'print "$. - $_"' filename
這個(gè)例子中的,沒用-ne,只是命令寫成了-n -e,其實(shí)一樣,這個(gè)例子中,是給當(dāng)前文件中的內(nèi)容都加一個(gè)行號(hào)打印出來.注:$.表示當(dāng)前行號(hào)。
復(fù)制代碼 代碼如下:
perl -pe '$_ = "$. $_"' filename
這個(gè)其實(shí)和上面一樣,分別只是使用了-p替換了-n,這個(gè)有個(gè)什么好處啦,別的地方都一樣,但-p按行來遍歷完文件后,會(huì)給$_打印出來。相當(dāng)于awk分割域(awk‘{i = NF – 1; print $1 + $i}')。
復(fù)制代碼 代碼如下:
perl -lane 'print $F[0] + $F[-2]'
這個(gè)神奇的地方在于-a,使用-a后.因?yàn)?n分行讀進(jìn)來,然后-a給數(shù)據(jù)分割成@F的數(shù)組。
復(fù)制代碼 代碼如下:
perl -ne 'print if /^START$/ .. /^END$/'
打印正則中從$start到$end的地方
復(fù)制代碼 代碼如下:
perl -ne 'print if $. >= 15; exit if $. >= 17;'
有效地打印數(shù)字范圍中的行
復(fù)制代碼 代碼如下:
perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c
原地修改 -i 開關(guān)的神奇之處在于它對(duì) @ARGV 中的每個(gè)文件都用該腳本對(duì)該文件輸出所產(chǎn)生的文件版本進(jìn)行替代。
復(fù)制代碼 代碼如下:
perl -ne 'print scalar reverse $_' test
給文件中的內(nèi)容反向排序,比如文件中有fukai,就會(huì)變成iakuf.
替換
將所有C程序中的foo替換成bar,舊文件備份成.bak
復(fù)制代碼 代碼如下:
perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c
很強(qiáng)大的功能,特別是在大程序中做重構(gòu)。記得只有在UltraEdit用過,如果你不想備份,就直接寫成 perl -p -i -e 或者更簡(jiǎn)單 perl -pie
將每個(gè)文件中出現(xiàn)的數(shù)值都加一
復(fù)制代碼 代碼如下:
perl -i.bak -pe 's/(\d+)/ 1 + $1 /ge' file1 file2 ....
將換行符\r\n替換成\n
復(fù)制代碼 代碼如下:
perl -p -i -e 's/\r\n/\n/g' file
同dos2unix命令。
將換行符\n替換成\r\n
復(fù)制代碼 代碼如下:
perl -pie 's/\n/\r\n/g' file
同unix2dos命令。
取出文件的一部分
顯示字段0-4和字段6,字段的分隔符是空格
復(fù)制代碼 代碼如下:
perl -lane 'print "@F[0..4] $F[6]"' file
同 awk 'print $1, $2, $3, $4, $5, $7'。參數(shù)名稱lane也很好記。
如果字段分隔符不是空格而是冒號(hào),則用
復(fù)制代碼 代碼如下:
perl -F: -lane 'print "@F[0..4]\n"' /etc/passwd
顯示START和END之間的部分
復(fù)制代碼 代碼如下:
perl -ne 'print if /^START$/ .. /^END$/' file
相反,不顯示START和END之間的部分
復(fù)制代碼 代碼如下:
perl -ne 'print unless /^START$/ .. /^END$/' file
顯示開頭50行:
復(fù)制代碼 代碼如下:
perl -pe 'exit if $. > 50' file
同命令 head -n 50
不顯示開頭10行:
復(fù)制代碼 代碼如下:
perl -ne 'print unless 1 .. 10' file
顯示15行到17行:
復(fù)制代碼 代碼如下:
perl -ne 'print if 15 .. 17' file
每行取前80個(gè)字符:
復(fù)制代碼 代碼如下:
perl -lne 'print substr($_, 0, 80) = ""' file
每行丟棄前10個(gè)字符:
復(fù)制代碼 代碼如下:
perl -lne 'print substr($_, 10) = ""' file
搜索
查找comment字符串:
復(fù)制代碼 代碼如下:
perl -ne 'print if /comment/' duptext
這個(gè)就是普通的grep命令了。
查找不含comment字符串的行:
復(fù)制代碼 代碼如下:
perl -ne 'print unless /comment/' duptext
反向的grep,即grep -v。
查找包含comment或apple的行:
復(fù)制代碼 代碼如下:
perl -ne 'print if /comment/ || /apple/' duptext
相同的功能就要用到egrep了,語法比較復(fù)雜……
計(jì)算
計(jì)算字段4和倒數(shù)第二字段之和:
復(fù)制代碼 代碼如下:
perl -lane 'print $F[4] + $F[-2]'
要是用awk,就得寫成 awk '{i=NF-1;print $5+$i}'
排序和反轉(zhuǎn)
文件按行排序:
復(fù)制代碼 代碼如下:
perl -e 'print sort >' file
相當(dāng)于簡(jiǎn)單的sort命令。
文件按段落排序:
復(fù)制代碼 代碼如下:
perl -00 -e 'print sort >' file
多個(gè)文件按文件內(nèi)容排序,并返回合并后的文件:
復(fù)制代碼 代碼如下:
perl -0777 -e 'print sort >' file1 file2
文件按行反轉(zhuǎn):
復(fù)制代碼 代碼如下:
perl -e 'print reverse >' file1
相應(yīng)的命令有嗎?有,tac(cat的反轉(zhuǎn))
數(shù)值計(jì)算
10進(jìn)制轉(zhuǎn)16進(jìn)制:
復(fù)制代碼 代碼如下:
perl -ne 'printf "%x\n",$_'
10進(jìn)制轉(zhuǎn)8進(jìn)制:
復(fù)制代碼 代碼如下:
perl -ne 'printf "%o\n",$_'
16進(jìn)制轉(zhuǎn)10進(jìn)制:
復(fù)制代碼 代碼如下:
perl -ne 'print hex($_)."\n"'
8進(jìn)制轉(zhuǎn)10進(jìn)制:
復(fù)制代碼 代碼如下:
perl -ne 'print oct($_)."\n"'
簡(jiǎn)易計(jì)算器
復(fù)制代碼 代碼如下:
perl -ne 'print eval($_)."\n"'
批量重命名文件
以下是在verycd網(wǎng)站下載的資料,現(xiàn)對(duì)其改名的例子:
復(fù)制代碼 代碼如下:
$ ls
帝王之死001.mp3 帝王之死006.mp3
$ perl -MFile::Find -e 'find sub{ rename $_,substr($1,1,2).".mp3" if /(\d+)\.mp3$/;}, "." '
$ ls
01.mp3 06.mp3
$ ls
李斯傳奇 - 第001回.mp3
$ perl -MFile::Find -e 'find sub{ rename $_,$1.".mp3" if /(\d+)(.*)\.mp3$/;}, "." '
$ ls
001.mp3
$ ls
十二生肖妙品欣賞系列 01 子鼠精靈.pdf
$ perl -MFile::Find -e 'find sub{ rename $_,"$2$3".".pdf" if /(.*)\s(\d+)\s(.*)\.pdf$/;}, "." '
$ ls
01子鼠精靈.pdf
中文標(biāo)點(diǎn)符號(hào)替換(中文在此占3個(gè)字符位)
女人當(dāng)國$ ls
女人當(dāng)國01:選秀入宮.mp3 女人當(dāng)國16:“議政王”的奧妙.mp3
將'mp3'文件修改為:01.選秀入宮.mp3,像如下格式:
perl -MFile::Find -E 'find sub{ rename $_,"$1.$3".".mp3" if /(\d{2})([^u4E00-u9FA5]{3})(.*).mp3$/;}, "." '
女人當(dāng)國$ ls
01.選秀入宮.mp3 13.京城風(fēng)云動(dòng).mp3
...
秦瓊:“戰(zhàn)將”最終成“門神”(上).mp3
將'“”)'引號(hào)去掉
perl -MFile::Find -E 'find sub{ my $o=$_; s/“|”|)//g;rename $o,$_}, "." '
秦瓊:戰(zhàn)將最終成門神(上).mp3
將':('替換為'.'
perl -MFile::Find -E 'find sub{ my $o=$_; s/:|(|,/\./g;rename $o,$_}, "." '
秦瓊.戰(zhàn)將最終成門神.上.mp3
在數(shù)字編號(hào)后加入'.'
01石頭里生出美猴王.mp3
perl -MFile::Find -E 'find sub{my $o=$_;s/(^\d+)/$1\./;rename $o,$_},"."'
01.石頭里生出美猴王.mp3
將前置中文字符去掉
獨(dú)立書店_01.臺(tái)北.書店之城.1.mp3
perl -MFile::Find -E 'find sub{ my $o=$_; s/([^u4E00-u9FA5]{12}_)//g;rename $o,$_}, "." '
01.臺(tái)北.書店之城.1.mp3
在命令行下查看當(dāng)前目錄下的目錄
用于列出當(dāng)前目錄的目錄:一級(jí)目錄和所有目錄。
使用內(nèi)置的File::Find模塊
復(fù)制代碼 代碼如下:
perl -MFile::Find -E 'find sub{ print "$_," if(-d length >1) }, $File::Find::prune = 1, "." '
這將會(huì)列出所有的目錄,目前還寫不出僅列出當(dāng)前目錄下一級(jí)目錄。
使用File::Find::Rule模塊實(shí)現(xiàn)起來最比較容易
復(fù)制代碼 代碼如下:
perl -MFile::Find::Rule -E '@a=File::Find::Rule->directory->in(".");foreach(@a){say unless(/\/|\./)};'
perl -MFile::Find::Rule -E 'say for grep $_ ne ".", File::Find::Rule->maxdepth(1)->directory->in(".");'
對(duì)目錄下的文件進(jìn)行大小寫修改
復(fù)制代碼 代碼如下:
$ ls
CD1 CD2 CD3 CD4 CD5 CD6
$ perl -MFile::Find -e 'find sub{ rename $_,lc($1) if /(\w+\d$)/;}, "." '
$ ls
cd1 cd2 cd3 cd4 cd5 cd6
只是使用File::Find模塊的find子例程來實(shí)現(xiàn)目錄遍歷,對(duì)符合條件的文件作重命名而已。
統(tǒng)計(jì)相關(guān)的tcp連接情況
查看ip尾數(shù)為9且端口為80的所有連接
復(fù)制代碼 代碼如下:
netstat -naut|grep 9:80|perl -F'\s+' -alne '$F[4]=~/(.*)\:\d+/;$F[4]=$1;$s{$F[4]}++;' -e 'END { foreach (sort {$a=>$b} keys %s){print "$_ \: $s{$_}"} }'
查看ip尾數(shù)為9且端口為80的所有連接,按連接數(shù)從多到少排列,顯示前20個(gè)ip
復(fù)制代碼 代碼如下:
netstat -naut|grep 9:80|perl -F'\s+' -alne '$F[4]=~/(.*)\:\d+/;$F[4]=$1;$s{$F[4]}++;' -e 'END {foreach (sort {$s{$b}=>$s{$a}} keys %s){print "$_ \: $s{$_}"} }' |head -20
查看ip尾數(shù)為9且端口為80的所有連接,統(tǒng)計(jì)連接狀態(tài)信息
復(fù)制代碼 代碼如下:
netstat -naut|grep 9:80|perl -F'\s+' -alne '$s{$F[5]}++;' -e 'END { foreach (keys %s){chomp($_);print "$_ \: $s{$_}"} }'
統(tǒng)計(jì)一文本文件有多少行:
復(fù)制代碼 代碼如下:
perl -le 'open FILE, "file_name"; @_=FILE>; print $.'
perl -e 'print scalar(()=>),"\n"' file_name
perl -wE'say~~(()=>)' file_name
perl -e'print scalar(()=>)' file_name
perl -lne 'END{print $.}' file_name
perl -le 'print $==()=>' file_name
perl -ne 'print $. if eof' file_name
wc -l file_name
cat file_name |wc -l
more file_name |wc -l
注:經(jīng)對(duì)一個(gè)包含六百多萬行的文件進(jìn)行處理,發(fā)現(xiàn)'wc -l'的效率是最好的。
其他
啟動(dòng)交互式perl:
復(fù)制代碼 代碼如下:
perl -de 1
查看包含路徑的內(nèi)容:
復(fù)制代碼 代碼如下:
perl -le 'print for @INC'
perl 生成隨機(jī)密碼
主要還是借用'rand'函數(shù)來實(shí)現(xiàn)。
復(fù)制代碼 代碼如下:
$random = int( rand( $Y-$X+1 ) ) + $X;
下面的示例將會(huì)輸出25-75之間的隨機(jī)數(shù):
復(fù)制代碼 代碼如下:
$random = int( rand(51)) + 25;
print "$random\n";
The rand function returns a fractional number, from (and including) 0 up to (but not including) its argument. We give it an argument of 51 to get a number that can be 0 or more, but never 51 or more. We take the integer portion of this to get a number from 0 to 50, inclusive (50.99999.... will be turned
into 50 by int). We then add 25 to it to get a number from 25 to 75, inclusive.
從數(shù)組中隨機(jī)返回元素
復(fù)制代碼 代碼如下:
$elt = $array[ rand @array ];
$elt = $array[ int( rand(0+@array) ) ];
生成8位包含特殊的隨機(jī)密碼
復(fù)制代碼 代碼如下:
@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ *) );
$password = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]);
可以據(jù)用戶
復(fù)制代碼 代碼如下:
use strict;
use warnings;
sub random_pwd {
my $length = shift;
my @chars = (0 .. 9, 'a' .. 'z', 'A' .. 'Z');
return join '', @chars[ map rand @chars, 0 .. $length ];
}
print random_pwd(42);
生成42位長(zhǎng)度的密碼
復(fù)制代碼 代碼如下:
use strict;
use warnings;
my @chars=("a".."z",0..9);
my $password="";
foreach(1..42){
my $char=$chars[int(rand(@chars))];
$char=uc($char) if rand() 0.5;
$password.=$char;
}
print $password . "\n";
-------------------------------
my @chars = ('0'..'9', 'a'..'z', 'A'..'Z');
my $passwd =
join '',
map $chars[rand(@chars)],
1..42;
調(diào)用String::Random模塊來實(shí)現(xiàn):
復(fù)制代碼 代碼如下:
use strict;
use warnings;
use String::Random 'random_regex';
print random_regex('[a-zA-Z]{42}'), "\n";
使用perl in one line來完成:
復(fù)制代碼 代碼如下:
perl -le "print map { ('a'..'z', 'A'..'Z', '0'..'9')[rand 62] } 1..42"
perl -le 'print map { ("a".."z")[rand 26] } 1..8'
perl -le 'print map { ("a".."z", 0..9)[rand 36] } 1..8'
perl -le 'print map { (q(a)..q(z))[rand(26)] } 1 .. 10'
相關(guān)問題參考:
--------------------------------------------------------------------------
Perl one-liner with single quote-perl命令行里處理單引號(hào)
示例如下:
復(fù)制代碼 代碼如下:
echo "a,b" | perl -F',' -lane 'print $F[0];'
'a'
echo "a,b" | perl -F',' -lane 'print qq('$F[0]');'
[0]
echo "a,b" | perl -F',' -lane 'print q('$F[0]');'
[0]
以上三種方法都不能達(dá)到預(yù)期,可以使用'-w'參數(shù)來進(jìn)行控制,但其在變量環(huán)境無法使用。
復(fù)制代碼 代碼如下:
perl -lwe "print q( i'am );"
i'am
perl -lwe "$b=q( didn't ); print $b"
這里卻沒有了輸出。
解決辦法:
1、使用'\''轉(zhuǎn)義。
復(fù)制代碼 代碼如下:
echo "a,b" | perl -F',' -lane 'print "'\''$F[0]'\''";'
'a'
2、使用'''的ASCII碼
復(fù)制代碼 代碼如下:
echo "a,b" | perl -F',' -lane 'print "$F[0]\047";'
a'
echo "a,b" | perl -F',' -lane '$sq="\047"; print "$sq$F[0]$sq";'
您可能感興趣的文章:- Perl一句話命令行編程中常用參數(shù)總結(jié)
- perl 調(diào)試命令的相關(guān)知識(shí)小結(jié)
- Perl學(xué)習(xí)教程之單行命令詳解