參考連結
Perl 常用命令列選項
unix 常用命令 perl 實現 sed awk tr nl
perl 和sed,awk,tr,grep,nl等常用命令替換
sed
task |
sed |
perl |
Replace 12 with twelve |
sed 's/12/twelve/g' |
perl -pe 's/12/twelve/g' |
Replace the word sh with Bourne Shell |
sed -e 's/ sh / Bourne Shell /g' [1] |
perl -pe 's//bsh/b/Bourne Shell/g' [2] |
Remove lines 2 to 4 from stream |
sed '2,4d' |
perl -nle 'print if $.<2 || $.>4' |
awk
task |
awk |
perl |
Print second field (whitespace-separated) |
awk '{print $2}' |
perl -lane 'print $F[1]' |
Count lines starting with X |
awk '/^X/ {++x} END {print x}' |
perl -nle '++$x if /^X/; print $x if eof' |
Add numbers in second column and print sum |
awk '{sum+=$2} END {print sum}' |
perl -lane '$sum+=$F[1]; print $sum if eof' |
tr
task |
tr |
perl |
ROT13 |
tr 'A-Za-z' 'N-ZA-Mn-za-m' |
perl -pe 'y/A-Za-z/N-ZA-Mn-za-m/' |
Remove carriage return from DOS files [3] |
tr -d '/r' |
perl -pe 'tr//r//d' |
grep
task |
grep |
perl |
Print only lines containing 12 |
grep '12' |
perl -nle 'print if /12/' |
Print only lines not containing 12 |
grep -v '12' |
perl -nle 'print if !/12/' |
nl
task |
nl |
perl |
Insert line numbers (lined up) |
nl -ba |
perl -nle 'printf "%6s %s/n", $., $_' |
Perl命令列Perl參數:可以讓短小的Perl程式運行在Perl命令列.
1:-e
可以讓Perl程式在Perl命令列上運行.
例如,我們可以在Perl命令列上運行"HelloWorld"程式而不用把它寫入檔案再運行.
$perl-e'print"HelloWorld\n"'
多個-e也可以同時使用,運行順序根據它出現的位置.
$perl-e'print"Hello";'-e'print"World\n"'
象所有的Perl程式一樣,只有程式的最後一行不需要以;結尾.
2:-M
可以象通常一樣引用模
$perl-MLWP::Simple-e'getstore("http://www.163.com/","163.html"'##下載整個網頁
-M+模組名和use模組名一樣
第三部分:隱式迴圈
3:-n
增加了迴圈的功能,使你可以一行一行來處理檔案
$perl-n-e'print;'1.txt#####$perl-ne'print;'1.txt
這與下面的程式一樣.
- LINE:
- while(<>){
- print;
- }
<>開啟Perl命令列裡的檔案,一行行的讀取.每一行預設儲存在$_
$perl-n-e'print"$.-$_"'file
上面的這一行可以寫成
- LINE:
- while(<>;){
- print"$.-$_"
- }
輸出當前行數$.和當前行$_.
4:-p,和-n一樣,但是還會列印$_的內容
如果想在迴圈的前後做些處理,可以使用BEGIN或ENDblock.下面的這一行計算檔案裡的字數.
$perl-ne'END{print$t}@w=/(\w+)/g;$t+=@w'file.txt
每一行所有匹配的字放入數組@w,然後把@w的元素數目遞加到$t.ENDblock裡的print最後輸出檔案總字數.
還有兩個參數可以讓這個程式變得更簡單.
5:-a
開啟自動分離(split)模式.空格是預設的分離號.輸入根據分離號被分離然後放入預設數組@F
使用-a,上面的命令可以寫成這樣:
$perl-ane'END{print$x}$x+=@F'file.txt##使用了-a
6:-F
把預設的分離號改為你想要的.例如把分離號定為非字元,上面的命令可以改為:
$perl-F'\W'-ane'END{print$x}$x+=@F'file.txt
下面通過Unixpassword檔案來介紹一個複雜的例子.Unixpassword是文字檔,每一行是一個使用者記錄,
由冒號:分離.第7行是使用者的登入shell路徑.我們可以得出每一個不同shell路徑被多少個使用者使用:
$perl -F':' -ane '$s{$F[6]}++;'\>;-e'END{print"$_=$s{$_}"for keys %s }' /etc/passwd
雖然現在不是一行,但是你可以看出使用參數可以解決什麼問題.
第四部分:RecordSeparators資料分隔字元
$/和$\--輸入,輸出分隔號.
$/用來分隔從檔案控制代碼裡讀出的資料,預設$/分隔號是\n,這樣每次從檔案控制代碼裡就會一行行的讀取
$\預設是Null 字元,用來自動加到要print的資料尾端.這就是為什麼很多時候print都要在末尾加上\n.
$/和$\可與-n-p一起使用.在Perl命令列上相對應為-0(零)和-l(這是L).
-0後面可以跟一個16進位或8進位數值,這個值用來付給$/.
-00開啟段落模式,-0777開啟slurp模式(即可以一次把整個檔案讀入),這與把$/設為空白字元和undef一樣效果.
單獨使用-l有兩個效果:
第一:自動chomp輸入分隔號
第二:把$/值付給$\(這樣print的時候就會自動在末尾加\n)
1:-l參數,用來給每一個輸出加\n.例如
$perl-le'print"HelloWorld"'
第五部分:原位編輯
使用已有的參數我們可以寫出很有效Perl命令列程式.常見的UnixI/O重新導向:
$perl-pe'somecode'>output.txt
這個程式從input.txt讀取資料,然後做一些處理再輸出到output.txt.你當然也可以把輸出重新導向到同一個檔案裡.
上面的程式可以通過-i參數做的更簡單些.
2:-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經典的例子
問題:
遇到一問題:
aaa@domain.com2
aaa@domain.com111
bbb@home.com2222
bbb@home.com1
類似這種輸出,我想把他們變換成下面形式:
aaa@domain.com113
bbb@home.com2223
就是將相同郵箱名稱後面的數字相加。各位大俠能否給些思路如何用perl來實現。
答案:perl-anle'$cnt{$F[0]}+=$F[1];END{print"$_\t$cnt{$_}"forkeys%cnt}'urfile
如果熟悉了上面幾個Perl命令列參數的用法,上面的這個命令應該很好理解:
每次讀取urfile的一行,由於使用了-a,開啟自動分離(split)模式.空格是預設的分離號.輸入根據分離號被分離然後放入預設數組@F中,
以檔案的第一行為例子$F[0]就是aaa@domain.com,$F[1]就是2
$cnt{$F[0]}+=$F[1]就是一個雜湊數組,以$F[0]為key,$F[1]為value,把相同key的數值都疊加起來.然後把檔案的每一行都這樣處理一次.
END{}就是在迴圈完之後再處理.裡面的意思就是列印這個%cnt雜湊數組.這個雜湊數組的key就是郵箱名稱,value就是疊加後的數字.
下面的是上面行命令的文本形式:
- #!/usr/bin/perl
- usestrict;
- usewarnings;
- my%hash;
- while(<>){
- chomp;
- my@array=split;
- $hash{$array[0]}+=$array[1];
- }
- END{
- foreach(keys%hash){
- print"$_\t$hash{$_}\n";
- }
- }
完