perl 命令行程序

 

命令行程序

下面的幾個 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 函數。

隱式循環

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

$ perl

 -n -e 'some code' file1

這與下面的程序一樣.

  LINE:
while (<>) {
# your code goes here
}

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

$ perl

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

上面的這一行可以寫成

  LINE:
while (<>) {
print "$. - $_"
}

輸出當前行數 $. 和當前行 $_. -p 可以讓上面的程序變得更容易.-p 會輸出 $_ 的內容,就像這樣:

  LINE:
while (<>) {
# your code goes here
} continue {
print or die "-p destination: $!/n"$$
}

continue 在這裏保證 print 在每次循環都會被調用。

使用 -p,我們的打印行數程序可以改爲

$ perl

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

這種情況下我們就不需要要明確地調用 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 是文本文件,每一行是一個用戶記錄,由冒號 :分離。 第?行是用戶的登錄 shell 路徑。我們可以得出每一個不同 shell 路徑被多少個用戶使用:

$ perl

 -F':' -ane '$s{$F[6]}++;' /
> -e 'END { print "$_ : $s{$_}" for keys %s }' /etc/passwd

雖然現在不是一行,但是你可以看出使用參數可以解決什麼問題。

數據分隔符

我以前的文章裏提到過 $/ 和 $/ -- 輸入,輸出分隔號。$/ 用來分隔從文件句柄裏讀出的數據,缺省 $/ 分隔號是 /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' < input.txt > 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 是源文件的備份.

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