Perl命令行應用程序詳解

這篇文章主要介紹了Perl命令行應用程序詳解,本文大量講解了perl的命令行參數和一句話實現的一些功能,需要的朋友可以參考下

perl - Practical Extraction and Report Language,Perl有很多命令行參數,通過它可以讓你的程序更簡練,並且可以寫出很多隻有一行命令的perl。在這篇文章裏我們來了解一些常用的命令行參數。

命令行調用


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 ]...

[開關項描述]

-0

規定記錄分隔符。

-0<數字>

(用8進製表示)指定記錄分隔符($/變量),默認爲換行

-00

段落模式,即以連續換行爲分隔符

-0777

禁用分隔符,即將整個文件作爲一個記錄

-a

與 -n 或者 -p 一起使用,負責打開自動拆分模式,用於對空白字符進行隱式拆分,用空格分隔$_並保存到@F中,相當於@F=split ''。分隔符可以使用-F參數指定例如:


date | perl -ane 'print "$F[0]\n"';

-c

只檢查 Perl 腳本語法,而不執行腳本。

-d

對腳本打開 Perl調試器。

-D

設置 Perl 的調試標記(請先檢查 Perl 的安裝情況,確保已經安裝了調試器),若要觀察 Perl 是如何執行腳本的,可使用 -D14。

-e command

用於再命令行而不是在腳本中執行 Perl 命令。

-F pattern

規定拆分輸入行時使用的模式。模式是位於斜槓、單引號或雙引號之間的正則表達式。例如,-F/:+/ 表示在一個或多個冒號上拆分輸入行,如果 -a 仍然起作用的話,則打開它。

-h

打印 Perl 的命令選項列表。

-i extension

在使用 <> 循環遍歷文件時啓用原位編輯模式。 如果沒有規定擴展名的話,則原位修改各行內容,否則使用擴展名來修改輸入文件名(以便充當備份文件),並使用原位編輯的原文件名創建輸出文件。 這也是所有 print 語句選擇的文件句柄。

-I directory
與 -P選項一起使用,負責告訴 C 預處理程序查找包含的文件,其默認目錄包括 /usr/included、/usr/lib/perl 以及當前目錄。

-1 digits
啓用自動行結束處理。如果使用了 -n 或者 -p 選項,則去掉終止符。把位數(八進制) 賦值給 $\ ,並將行終止符添加到 print 語句中。如果沒有規定位數的話,則將 $\ 設置爲 $/ 的當前值。

-l
對輸入內容自動chomp,對輸出內容自動添加換行。使用 -l 有兩個效果,第一自動 chomp 輸入分隔號,第二 把$/ 值付給 $\ (這樣 print 的時候就會自動在末尾加 \n)


-m [-] module
-M [-] module
-M [-] module'
-[mM] module =
arg [,arg]..
-m module

在執行 Perl 腳本之前執行 use 方法。

-M module
再執行 Perl 腳本之前執行 use 方法。如果添加附加的文本,則可使用引號。方括號中的短橫線表示把 use 指令替換爲 no。

-n
使 Perl 隱式地循環遍歷指定的文件,並只打印規定的行。自動循環,相當於 while(<>) { 腳本; }

-p
使 Perl 隱式地循環遍歷指定的文件,同時打印所有的行。自動循環+自動輸出,相當於 while(<>) { 腳本; print; }

-P
使要運行的腳本在 Perl 編譯之前通過 C 預處理程序。

-s
再腳本名之後、文件名參數之前啓用開關項解析,並從@ARGV 數組中刪除所有找到的開關項。將開關項設置爲同名的標量型變量,並將標量賦值爲 1 。例如,-abc 在腳本中將轉換爲 $abc。

-S
如果不支持 #!/usr/bin/perl 行,則讓 Perl 在 PATH 環境變量中搜索腳本。

-T
強制打開“污染“ 檢查,用於測試腳本,一般只用在 setuid 或 setgid 程序上。推薦自行檢查 CGI 腳本。

-u
編譯後產生腳本的核心轉儲(基於 UNIX 系統)。

-U
允許 Perl 執行不安全的操作,如果是超級用戶的話,則斷開目錄鏈接。

-v
打印 Perl 的版本信息。

-V
打印最重要的 Perl 配置項和數組 @INC 中當前值的彙總。

-V:NAME
打印 NAME 的值,其中 NAME 是配置變量。

-w
打印警告信息,包括錯誤使用保留字、文件句柄、子例程等情況。

-W
啓用所有警告,而不論是否已經用 no warnings 關閉了本地警告。

-x directory
忽略 #!/usr/bin/perl 行之前的任何文本。如果將目錄名當作 -x 開關的參數,則 Perl 會在開始執行腳本之前自動切換到該目錄。

-X
關閉所有警告。

每一行將缺省保存在 $_,-p 和 -n 一樣,但是還會打印 $_ 的內容。

請注意:-p 開關和 -n 開關的使用。當您想顯式打印數據時,使用 -n 開關。-p 開關隱式地將 print $_ 語句插入到 -n 開關所產生的循環中。因此,-p 開關更適用於對文件進行的完全處理,而 -n 開關更適用於選擇性文件處理,這樣的處理只需打印特定數據。

安全網參數
有三個參數我認爲可以起到“安全網”的作用,因爲它們可以讓你避免犯錯,特別是當你在使用 Perl 嘗試一些特別聰明(或這愚蠢)的想法時,錯誤難免會發生。有經驗的 Perl 程序員常常使用這三個參數來提前找到錯誤所在。

-c 是第一個。這個參數編譯 Perl 程序但並不真正運行它,由此檢查所有語法錯誤,每次修改 perl 程序之後我都會立刻使用它來找到任何語法錯誤。


$ perl -c program.pl

這保證了程序依然可以編譯。很顯然,當你輸入一小段代碼之後立即進行檢查,比起一下子輸入幾百行代碼然後開始 debug 要容易很多。

-W 是第二個參數。它會提示你任何潛在的bug。Perl 5.6.0 之後的版本已經用 use warnings; 替換了-w。你應該使用 use warnings 因爲它要比 -w 更靈活。

-T 是第三個參數。它讓 perl 出於了 taint 模式中。在這個模式裏,Perl 會質疑任何程序外傳來的數據。例如從命令行讀取,外部文件裏讀取或是 CGI 程序裏傳來的數據。這些數據在 -T 模式裏都會被 Tainted(污染),Tainted 數據不可以被用來和外部交互。例如使用在 system 調用和用作 open 的文件名,關於什麼數據會被Tainted,請參閱perlsec 文檔,那裏有一個完整的列表。

要想使用 Tainted 的數據就必須 untaint這個數據。untaint是通過正則表達式來實現的,關於 taint 本身的內容足夠寫一篇單獨的文章,所以這裏我不會太多的講述 taint 模式。如果你要編寫的程序(例如 CGI 程序)需要從從用戶那裏接受不可知的輸入,我推薦使有 taint 模式。

還有一個值得一提的參數是 -d,它將讓 Perl 處於 Debugger 模式。這個話題內容非常多,我推薦閱讀文檔 ‘perldoc perldebug'或 Richard Foley 的 Perl Debugger Pocket Reference 一書.

使用模塊
下面的幾個 Perl 參數可以讓短小的 Perl 程序很容易的在命令行上運行,-e 可以讓 Perl代碼在命令行上被編譯器直接執行。例如,我們可以直接在命令行上運行“Hello World” 程序而不用把它寫稱 Perl 程序。


$ perl -e 'print "Hello World\n"'

多個 -e 也可以同時使用,運行順序根據它出現的位置。


$ perl -e 'print "Hello ";' -e 'print "World\n"'

象所有的 Perl 程序一樣,只有程序的最後一行不需要以 ; 結尾,你也可以用 -e 來引用模塊,但 -M 讓它變得更容易。


$ perl -MLWP::Simple -e 'print head "http://www.example.com"'

-M模塊名和use 模塊名一樣。有些模塊有默認的模塊導入,如果你不想導入它們,你可以使用-m。-m模塊名和 use module() 一樣,關閉了默認的導入。例如下面這個例子,因爲 head 函數是默認導入,而使用-m 時就不會執行,結果是沒有輸出。


$ perl -mLWP::Simple -e 'print head "http://www.example.com"'

-m 和 -M 有很多方便的語法來幫助你使用它們,你可以在 = 後面列出對 use 的各種參數。


$ perl -MCGI=:standard -e 'print header'

在這裏,CGI.pm 的 :standard 被引入,header 函數因此可以使用。要引入多個參數可以通過使用引號和逗號。


$ perl -MCGI='header,start_html' -e 'print header,start_html'

這裏我們引入了 header 和 start_html 函數。

Implicit Loops
-n 和 -p 增加了循環的功能,使你可以一行一行來處理文件。


$ perl -n -e 'some code' file1

這與下面的程序一樣.
LINE:


while () {
# your code goes here
}

注意:打開命令行裏的文件,一行行的讀取,每一行將缺省保存在 $_。


$ perl -n -e 'print "$. - $_"' file

上面的這一行可以寫成 LINE: while () { print ”$. – $_” } 輸出當前行數 $. 和當前行 $_,-p可以讓上面的程序變得更容易,-p 會輸出 $_ 的內容,就像這樣:


while () {
# your code goes here
} continue {
print or die "-p destination: $!\n";
}

continue 在這裏保證 print 在每次循環都會被調用。使用 -p,我們的打印行數程序可以改爲


$ perl -p -e '$_ = "$. - $_"' filename

這種情況下我們就不需要要明確地調用 print 函數了,因爲 -p 選項已經調用了它。注意,LINE: 標籤可以讓我們直接跳到下一個輸入記錄,而不管你進入了多少層循環,使用 next LINE。


$ perl -n -e 'next LINE unless /pattern/; print $_'

當然,也可以這樣寫:


$ perl -n -e 'print unless /pattern/'

在更復雜的情況裏,next LINE可以讓你的代碼更容易理解。如果想在循環的前後做些處理,可以使用 BEGIN或END block,下面的這一行代碼可以計算 text 文件裏的字數:


$ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt

每一行所有匹配的字放入數組 @w,然後把 @w 的元素數目遞加到$t,END block 裏的 print 最後輸出文件總字數。

還有兩個參數可以讓這個程序變得更簡單,-a 打開自動分離 (split) 模式,空格是缺省的分離號,輸入根據分離號被分離然後放入缺省數組 @F。由此,我們可以把上面的程序改寫爲:


$ perl -ane 'END {print $x} $x += @F' file.txt

你也可以通過 -F 把缺省的分離號改爲你想要的.例如把分離號定爲非字符:


$ perl -F'\W' -ane 'END {print $x} $x += @F' file.txt

下面通過 Unix password 文件來介紹一個複雜的例子。Unix password 是文本文件,每一行是一個用戶記錄,由冒號 ':'分離。第6列是用戶的登錄 shell 路徑,我們可以得出每一個不同 shell 路徑被多少個用戶使用:


$ 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

有如下輸出:


/usr/sbin/nologin : 3
/bin/sh : 18
/bin/sync : 1
/bin/bash : 2
/bin/false : 9

數據分隔符
我以前的文章裏提到過 $/ 和 $\—輸入,輸出分隔號。$/ 用來分隔從文件句柄裏讀出的數據,缺省 $/ 分隔號是 \n,這樣每次從文件句柄裏就會一行行的讀取。$\ 缺省是空字符,用來自動加到要 print 的數據尾端。這就是爲什麼很多時候 print 都要在末尾加上 \n,$/ 和 $\ 可與 -n -p 一起使用。在命令行上相對應爲 -0 (零) 和 -l (這是 L)。-0 後面可以跟一個16 進制或8進制數值,這個值用來賦給 $/。-00 打開段落模式,-0777 打開slurp 模式(即可以一次把整個文件讀入),這與把 $/ 設爲空字符和 undef 一樣效果。

單獨使用 -l 有兩個效果,第一自動 chomp 輸入分隔號,第二 把$/ 值付給 $\ (這樣 print 的時候就會自動在末尾加 \n)我個人常常使用 -l 參數,用來給每一個輸出加 \n,例如:


$ perl -le 'print "Hello World"'

原位編輯
使用已有的參數我們可以寫出很有效的命令行程序. 常見的Unix I/O 重定向:


$ perl -pe 'some code' output.txt

這個程序從 input.txt 讀取數據,然後做一些處理再輸出到 output.txt. 你當然也可以把輸出重定向到同一個文件裏。上面的程序可以通過 -i 參數做的更簡單些。-i 把源文件更名然後從這個更名的源文件裏讀取,最後把處理後的數據寫入源文件。如果 -i 後跟有其他字符串,這個字符串與源文件名合成後來生成一個新的文件名,此文件會被用來儲存原始文件以免被 -i 參數覆蓋。

這個例子把所有php字符替換爲perl :


$ perl -i -pe 's/\bPHP\b/Perl/g' file.txt

程序讀取文件的每一行,然後替換字符,處理後的數據重新寫入(即覆蓋) 源文件. 如果不想覆蓋源文件,可以使用$perl -i.bak -


pe 's/\bPHP\b/Perl/g' file.txt

這裏處理過的數據寫入 file.txt ,file.txt.bak 是源文件的備份。

打開Perl的taint模式
1、該程序的輸入數據來自外部數據源。
2、該程序所調用sub-shell或者函數影響到該程序之外其它東西。

你可以用“-T”開關來打開Perl的taint模式。當打開taint模式時,Perl就會進行執行檢查以確保你的數據未被taint,如果不安全的使用了被taint的數據,就會發出嚴重錯誤。爲了使你的數據不被taint,執行正則表達式來匹配數據並提取匹配部分。這樣你就必須描述出你所期望的數據的內容以及格式,並只接受符合這一要求的數據。

例如,假設你期望收到一個單詞字符(word characters,即字母數字以及下劃線),那麼下面的代碼通過一個正則表達式(它只通過全部由單詞字符組成字符串)會“蒸餾出”你的數據來:


if ($data =~ /^(\w+)$/) {
$data = $1;
} else {
die ”Error: tainted data found: $data\n”;
}

Perl命令行調試
缺省的Perl調試器就是perl解釋器本身,另外還有圖形界面的調試器。圖形界面的調試器推薦ptkdb,這裏不再進行介紹,下載安裝以後用兩次便會。所以這裏主要介紹一下缺省的命令行調試器的用法,一般的調試,用下面這些命令已經足夠了,這些命令說明也來自網上整理而成。

用 -d 命令行選項啓動Perl解釋器,例如:
perl -d test.pl 即進入Perl調試器的交互界面。

調試命令列表如下:(所有命令都在調試提示符下頂格輸入,命令大小寫有關)
h:顯示調試器的幫助信息。
|h:以分頁形式顯示調試器的幫助信息。
h h:顯示一個壓縮的幫助信息。
h 調試命令:顯示某個調試命令的幫助。
p 表達式:顯示變量或表達式的值,不顯示覆雜變量嵌入的結構和數據。
x 表達式:顯示變量或表達式的值,對較爲複雜的變量,以一種可讀形式顯示嵌入的結構和數據。
V 包名 變量名列表:顯示指定包內的所有(或部分)變量的值。(缺省的包名爲 main)
X 變量名列表:顯示當前包內所有(或部分)變量的值。

注:V、X命令中的變量名列表以空格分隔且變量名前應去掉$、@或%。

T:程序的調用棧回退一級。
s 表達式:單步執行,進入子函數。(step into)如果提供一個表達式並且表達式中包括函數調用,則單步進入該函數內。
n 表達式:單步執行,越過子函數。(step over)
c 行號/函數名:執行到某一行或某一個函數。
l:顯示未執行的一窗(一屏)文件內容。
l min-max:顯示第min到第max行的文件內容。
l 行號:顯示指定行的內容。
l 函數名:顯示指定函數的一窗(一屏)文件內容。
w 行號:顯示某行周圍一窗(一屏)文件內容。
f 文件名:切換到另一個文件。
/模式:在當前文件中向前(文件尾)查找匹配的字符串。
?模式:在當前文件中向後(文件頭)查找匹配的字符串。
L:顯示所有斷點和附加操作。
S 模式:顯示匹配(或不匹配,在模式前加!)的函數名。
t:切換跟蹤模式。
t 表達式:跟蹤執行表達式過程。
b 行號 條件:在某一行設置一個斷點,當程序執行到該行並且條件滿足時,產生中斷。
b 函數名 條件:在某函數上設置一個斷點,當程序執行到該函數並且條件滿足時,產生中斷。
b load 文件名:在某個文件的第一個可執行語句上設置一個斷點。
d 行號:刪除某一行的斷點。
D:刪除所有斷點。
a 行號 命令:給程序的某一行加一個附加操作。在執行該行語句前先執行附加的操作。
A:刪除所有已安裝的附加操作。
W 表達式:增加一個監視項。
W:刪除所有監視項。
O 選項名?:查詢調試器可選項的值。
O 選項名=選項值:設置調試器可選項的值。
lt Perl語句:設置一個操作顯示調試提示符前執行的操作。
ltlt Perl語句:增加一個顯示調試提示符前執行的操作。
gt Perl語句:設置一個離開調試提示符(轉入運行態)時執行的操作。
gtgt Perl語句:增加一個離開調試提示符(轉入運行態)時執行的操作。
{ 調試命令:設置一個操作顯示調試提示符前執行的操作。
{{ 調試命令:設置一個操作顯示調試提示符前執行的操作。
注:上述Perl語句和調試命令均可輸入多行,行尾以\轉義。
!number:重新執行以前第number次執行的調試命令。
!-number:重新執行現在以前number次執行的調試命令。
!模式:重新執行以前執行過的與模式匹配的調試命令。
!!命令:不退出調試器執行一個shell命令。
H-number:顯示以前執行的number條調試命令。如果省略number,則顯示所有執行過的調試命令。
R:重新啓動正在調試的程序。
q或^D:退出調試器。
|調試命令:將調試命令的輸出分頁顯示。
||調試命令:類似|調試命令,適於有大量輸出的調試命令,例如:|V main。
= 別名 值:給某個調試命令一個別名,例如:= quit q。

所有未識別的命令:當作插入的一條Perl語句執行。(使用eval)
Perl調試器的功能還有很多,可以設置很多選項來定製調試器的環境,它本身也是用Perl開發的,並且Perl發佈中還有接口讓你能開發其它的Perl調試器。如果要用Perl開發大的項目,有必要詳細瞭解這些細節。使用調試器和設置調試器選項的例子請參考Perl發佈中關於perldebug的文檔。

更多信息
Perl有大量的命令行參數,這篇文章只是列舉了最有用的一小部分,更詳細的信息請參考“perlrun” 文檔。

命令行的運用
用perl做命令行的一些簡單的介紹,來替代sed、awk之類的軟件。

Perl作爲命令行實用程序,可以度參考ibm的這篇文章。作者提到的很重要的一點是:有經驗的程序員不應迴避快速而又難看的解決方案。

Perl單行命令示例
我們先看看perl如何接收用戶的參數。如下,Dumper模塊不用理會,只是它會給數據結構打印出來,shell給接收到的參數都放到了@ARGV這個數組。


perl -MData::Dumper -e 'print Dumper \@ARGV' a b -w
$VAR1 = [
'a',
'b',
'-w'
];

如上,perl可以直接接收到shell命令行的參數。“-e”後的任何內容並將它當作腳本來運行。“-M”參數表示獲取其後的任何內容並將該內容作爲模塊導入,類似於正規腳本中的“use ModuleName”。我們可以看到象所有的 Perl 程序一樣,只有程序的最後一行不需要以 ; 結尾。

注:-e在單行命令中非常的重要,做單行命令時一定要加入在使用perl的單行命令時要注意使用”,不要使用"",其實sed和awk也是一樣,當然這只是一個建議,看下面的例子就能明白:


perl -e 'print "$$\n"'
5719

'$$'在perl中表示當前的pid,如果使用的是單引號,其中還可以放雙引號,還有變量,重要的是,這些變量不用擔心被shell轉義。


perl -pi -e 's/aaa/bbb/' filename

修改當前file文件中的文件,不生成中間文件,速度很快.記住 -i 開關,因爲它讓你原地編輯文件。


perl -ne 'print if /^int/' filename

象grep一樣過濾文件中需要的內容。這個地方,使用了-n,所以一次是做一行的操作,直到整個文件讀完。另外,在管道時,-n也會一樣,來遍歷管道送過來的內容。


perl -n -e 'print "$. - $_"' filename

這個例子中的,沒用-ne,只是命令寫成了-n -e,其實一樣,這個例子中,是給當前文件中的內容都加一個行號打印出來.注:$.表示當前行號。


perl -pe '$_ = "$. $_"' filename

這個其實和上面一樣,分別只是使用了-p替換了-n,這個有個什麼好處啦,別的地方都一樣,但-p按行來遍歷完文件後,會給$_打印出來。相當於awk分割域(awk‘{i = NF – 1; print $1 + $i}')。


perl -lane 'print $F[0] + $F[-2]'

這個神奇的地方在於-a,使用-a後.因爲-n分行讀進來,然後-a給數據分割成@F的數組。


perl -ne 'print if /^START$/ .. /^END$/'

打印正則中從$start到$end的地方


perl -ne 'print if $. >= 15; exit if $. >= 17;'

有效地打印數字範圍中的行


perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c

原地修改 -i 開關的神奇之處在於它對 @ARGV 中的每個文件都用該腳本對該文件輸出所產生的文件版本進行替代。


perl -ne 'print scalar reverse $_' test

給文件中的內容反向排序,比如文件中有fukai,就會變成iakuf.

替換
將所有C程序中的foo替換成bar,舊文件備份成.bak


perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c

很強大的功能,特別是在大程序中做重構。記得只有在UltraEdit用過,如果你不想備份,就直接寫成 perl -p -i -e 或者更簡單 perl -pie

將每個文件中出現的數值都加一


perl -i.bak -pe 's/(\d+)/ 1 + $1 /ge' file1 file2 ....

將換行符\r\n替換成\n


perl -p -i -e 's/\r\n/\n/g' file

同dos2unix命令。

將換行符\n替換成\r\n


perl -pie 's/\n/\r\n/g' file

同unix2dos命令。

取出文件的一部分
顯示字段0-4和字段6,字段的分隔符是空格


perl -lane 'print "@F[0..4] $F[6]"' file

同 awk 'print $1, $2, $3, $4, $5, $7'。參數名稱lane也很好記。

如果字段分隔符不是空格而是冒號,則用


perl -F: -lane 'print "@F[0..4]\n"' /etc/passwd

顯示START和END之間的部分


perl -ne 'print if /^START$/ .. /^END$/' file

相反,不顯示START和END之間的部分


perl -ne 'print unless /^START$/ .. /^END$/' file

顯示開頭50行:


perl -pe 'exit if $. > 50' file

同命令 head -n 50

不顯示開頭10行:


perl -ne 'print unless 1 .. 10' file

顯示15行到17行:


perl -ne 'print if 15 .. 17' file

每行取前80個字符:


perl -lne 'print substr($_, 0, 80) = ""' file

每行丟棄前10個字符:


perl -lne 'print substr($_, 10) = ""' file

搜索
查找comment字符串:


perl -ne 'print if /comment/' duptext

這個就是普通的grep命令了。

查找不含comment字符串的行:


perl -ne 'print unless /comment/' duptext

反向的grep,即grep -v。

查找包含comment或apple的行:


perl -ne 'print if /comment/ || /apple/' duptext

相同的功能就要用到egrep了,語法比較複雜……

計算
計算字段4和倒數第二字段之和:


perl -lane 'print $F[4] + $F[-2]'

要是用awk,就得寫成 awk '{i=NF-1;print $5+$i}'

排序和反轉
文件按行排序:


perl -e 'print sort <>' file

相當於簡單的sort命令。

文件按段落排序:


perl -00 -e 'print sort <>' file

多個文件按文件內容排序,並返回合併後的文件:


perl -0777 -e 'print sort <>' file1 file2

文件按行反轉:


perl -e 'print reverse <>' file1

相應的命令有嗎?有,tac(cat的反轉)

數值計算
10進制轉16進制:


perl -ne 'printf "%x\n",$_'

10進制轉8進制:


perl -ne 'printf "%o\n",$_'

16進制轉10進制:


perl -ne 'print hex($_)."\n"'

8進制轉10進制:


perl -ne 'print oct($_)."\n"'

簡易計算器


perl -ne 'print eval($_)."\n"'

批量重命名文件
以下是在verycd網站下載的資料,現對其改名的例子:


$ 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

中文標點符號替換(中文在此佔3個字符位)
女人當國$ ls
女人當國01:選秀入宮.mp3      女人當國16:“議政王”的奧妙.mp3

將'mp3'文件修改爲:01.選秀入宮.mp3,像如下格式:
perl -MFile::Find -E 'find sub{ rename $_,"$1.$3".".mp3" if /(\d{2})([^u4E00-u9FA5]{3})(.*).mp3$/;}, "." '
女人當國$ ls
01.選秀入宮.mp3         13.京城風雲動.mp3

...
秦瓊:“戰將”最終成“門神”(上).mp3
將'“”)'引號去掉
perl -MFile::Find -E 'find sub{ my $o=$_; s/“|”|)//g;rename $o,$_}, "." '

秦瓊:戰將最終成門神(上).mp3

將':('替換爲'.'
perl -MFile::Find -E 'find sub{ my $o=$_; s/:|(|,/\./g;rename $o,$_}, "." '
秦瓊.戰將最終成門神.上.mp3

在數字編號後加入'.'
01石頭裏生出美猴王.mp3
perl -MFile::Find -E 'find sub{my $o=$_;s/(^\d+)/$1\./;rename $o,$_},"."'
01.石頭裏生出美猴王.mp3

將前置中文字符去掉
獨立書店_01.臺北.書店之城.1.mp3
perl -MFile::Find -E 'find sub{ my $o=$_; s/([^u4E00-u9FA5]{12}_)//g;rename $o,$_}, "." '
01.臺北.書店之城.1.mp3

在命令行下查看當前目錄下的目錄
用於列出當前目錄的目錄:一級目錄和所有目錄。
使用內置的File::Find模塊


perl -MFile::Find -E 'find sub{ print "$_," if(-d && length >1) }, $File::Find::prune = 1, "." '

這將會列出所有的目錄,目前還寫不出僅列出當前目錄下一級目錄。

使用File::Find::Rule模塊實現起來最比較容易


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(".");'

對目錄下的文件進行大小寫修改


$ 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子例程來實現目錄遍歷,對符合條件的文件作重命名而已。

統計相關的tcp連接情況
查看ip尾數爲9且端口爲80的所有連接


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尾數爲9且端口爲80的所有連接,按連接數從多到少排列,顯示前20個ip


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尾數爲9且端口爲80的所有連接,統計連接狀態信息


netstat -naut|grep 9:80|perl -F'\s+' -alne '$s{$F[5]}++;' -e 'END { foreach (keys %s){chomp($_);print "$_ \: $s{$_}"} }'

統計一文本文件有多少行:


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

注:經對一個包含六百多萬行的文件進行處理,發現'wc -l'的效率是最好的。

其他
啓動交互式perl:


perl -de 1

查看包含路徑的內容:


perl -le 'print for @INC'

perl 生成隨機密碼
主要還是借用'rand'函數來實現。


$random = int( rand( $Y-$X+1 ) ) + $X;

下面的示例將會輸出25-75之間的隨機數:


$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.

從數組中隨機返回元素


$elt = $array[ rand @array ];
$elt = $array[ int( rand(0+@array) ) ];

生成8位包含特殊的隨機密碼


@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
$password = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]);

可以據用戶


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位長度的密碼


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;

調用String::Random模塊來實現:


use strict;
use warnings;
use String::Random 'random_regex';

print random_regex('[a-zA-Z]{42}'), "\n";

使用perl in one line來完成:


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'

相關問題參考:
--------------------------------------------------------------------------
Perl one-liner with single quote-perl命令行裏處理單引號
示例如下:


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]

以上三種方法都不能達到預期,可以使用'-w'參數來進行控制,但其在變量環境無法使用。


perl -lwe "print q( i'am );"
i'am

perl -lwe "$b=q( didn't ); print $b"

這裏卻沒有了輸出。

解決辦法:
1、使用'\''轉義。


echo "a,b" | perl -F',' -lane 'print "'\''$F[0]'\''";'
'a'

2、使用'''的ASCII碼


echo "a,b" | perl -F',' -lane 'print "$F[0]\047";'
a'

echo "a,b" | perl -F',' -lane '$sq="\047"; print "$sq$F[0]$sq";'

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章