Perl One-Liners | Perl命令行學(xué)習(xí)1 -e參數(shù)

:本內(nèi)容需要點(diǎn)的perl編程基礎(chǔ),最好是讀過《perl語言入門》。

本系列是自己平常學(xué)習(xí)工作中的總結(jié),每一個(gè)實(shí)例均為我為了講解而設(shè)置的,自己試過的,如有錯(cuò)誤,望能見諒

Perl 命令行參數(shù) -e

perl One-Liners

說明

前言

之前在知乎上看到別人提問

“你見過哪些令你瞠目結(jié)舌的Perl代碼技巧?” —— 有的人說是perl可以寫詩,有的人就說是perl One-Liners。

Perl One-Liners簡(jiǎn)介

我一般就叫 Perl單行程序 ,那與平常寫perl腳本有什么區(qū)別呢?

  • 平常寫perl腳本
#!usr/bin/perl -w

# 比如打開文件,然后讀取文件,逐行打印出來
open FILE,"<","123.txt";
while(<FILE>){
    print $_;
}
close FILE;
  • 使用單行程序
cat 123.txt | perl -n -e 'print $_'

看起來的確是簡(jiǎn)潔一些,但是實(shí)際上簡(jiǎn)練只是一方面,我的老師曾經(jīng)說:

有的時(shí)候的確是簡(jiǎn)練,但更重要一點(diǎn)是 ——“流程化”。

什么意思呢?其實(shí)按照shell編程來看,很多時(shí)候都是很多個(gè)工具相互搭配干活,中間用管道將他們哥幾個(gè)串聯(lián)起來,這樣一前一后這種流程感是不是很強(qiáng)烈,有木有。就是知道干了什么事情,比較清晰明白。

例如某個(gè)流程是這樣

cat讀取文件到標(biāo)準(zhǔn)輸入中
awk預(yù)處理
grep篩選
perl個(gè)性化處理
cat--->awk-->grep-->perl

同時(shí),作為單行程序,在shell里面運(yùn)行是可以利用到linux的工具的,也就是說perl也可以摻和進(jìn)去,和里面的其他工具搭配干活的,比如cat,echo,ls,pwd,last,find,ps,parallel,sed,grep,awk等等好多工具。

對(duì)比之下有這樣一些區(qū)別

  • 腳本需要寫到文件中去然后才能運(yùn)行,而單行命令的使用與其他命令行工具一樣直接在終端或者shell中寫代碼或者直接復(fù)制之前的代碼,之后運(yùn)行就可以。
  • 單行程序可以搭配眾多l(xiāng)inux工具,使用管道串聯(lián)起來,形成流程處理。而編寫腳本雖然可以使用反引號(hào)或者system()或者exec()可以運(yùn)行l(wèi)inux工具,但是流程感沒有那么強(qiáng)烈。
  • 單行程序攜帶方便,比如在自己簡(jiǎn)書里面放一些代碼,到別處只需要登陸簡(jiǎn)書復(fù)制代碼就可以運(yùn)行了。
  • 單行程序一前一后的流程并不是固定的,不同需求的情況下通過組合流程中的不同部分可以得到需要的結(jié)果,將所有處理的過程寫到腳本中更改處理順序不方便,當(dāng)然也可以把perl單行寫到腳本中然后參與shell的命令行的運(yùn)行也是可以的。
  • 如果有的時(shí)候有些shell命令的用法你忘了,這個(gè)時(shí)候全部用perl命令行替代它的功能是可以的,就是說其實(shí)我感覺像是一些命令sed,grep,awk,sort,wc之類的命令的一些常見用法都可以用perl單行寫出來,這樣一來很多東西可以統(tǒng)一,但是可能不適用于單行而是適用于bash腳本了。

另外還有一點(diǎn)我忽略了,在滄浪之水v的博文《Perl programming and perl one line》里面提到了perl單行程序?qū)τ谡{(diào)試來說很方便,從而不需要IDE來。比如忘了某個(gè)函數(shù)的用法,你可以在單行里面直接開寫,而不用寫到文件里面,然后打開終端之后運(yùn)行文件......

其實(shí)這樣看來perl One-Liners有這么多好處,簡(jiǎn)練、流程化、可以搭配眾多Linux大佬工具,那都用它得了。但是如果僅僅只是使用perl來完成所有的事情,那么將perl單行中的代碼量增加很多,實(shí)際上寫接近五十行代碼的perl已經(jīng)不適合用perl One-Liners了,因?yàn)樵趕hell里面修改不方便,同時(shí)代碼的保存也是問題。那個(gè)時(shí)候好不如寫在腳本.pl文件里面了,同時(shí)對(duì)于使用較多模塊,或者自己寫包的形式就完全不適合用單行程序了。

打個(gè)比方,可能不太恰當(dāng),“perl單行程序就像是自行車,從家里哐當(dāng)推出去騎著就跑;而寫perl腳本就像是摩托車,從家里推車出來都要會(huì)兒時(shí)間,還得啟動(dòng),有時(shí)候可能熄火;自行車最后跑起來那的確是沒有摩托車快,也沒有摩托車跑得遠(yuǎn),但是它騎上去就開始跑了,輕便快捷,然后還有各種Linux工具的相互配合,進(jìn)行接力!有時(shí)候勝過直接寫perl腳本哦”。

perl單行 perl 腳本

好,廢話少說。

在之前先做一下準(zhǔn)備工作

首先你是用的是什么系統(tǒng)

Windows

說明:做生物信息學(xué)推薦使用linux,雖然現(xiàn)在windows 10下面有l(wèi)inux子系統(tǒng),可能配置某些工具的時(shí)候會(huì)出點(diǎn)問題。因?yàn)槲覍懳恼铝?xí)慣用我的筆記本寫,所以我用Windows演示。不過沒有關(guān)系,我下面的這些perl代碼是跨平臺(tái)的。

windows下沒有包含perl的解釋器,你需要先下載一個(gè)git for windows(不是github for windows)

或者下載一個(gè)完整版的cmder

這里推薦安裝git for windows(雖然cmder完整版包含了git for windows,但是cmder使用的perl單行程序來說有些差別,就是在-e參數(shù)后面不能用單引號(hào),需要用雙引號(hào),這與Linux和Mac上就有差別了,為了統(tǒng)一,就使用git for windows,然后在windows中的cmd中運(yùn)行perl命令行程序,只能用雙引號(hào)引起來,不方便后面的操作,沒有Linux命令,不利于后續(xù)的使用)
安裝好了之后,你會(huì)發(fā)現(xiàn)你的右鍵菜單多了點(diǎn)東西

  • Git GUI Here
  • Git Bash Here
右鍵菜單

如果沒有這兩個(gè)選項(xiàng),就按照C:\Program Files\Git\git-bash.exe這個(gè)路徑找

就我現(xiàn)在的理解(我剛用這個(gè)軟件),就是相當(dāng)于把linux的shell里面的命令搬到windows下面運(yùn)行,同時(shí)也搬了perl的一些核心功能過來,所以我們就可以用這個(gè)軟件來使用Linux下面的perl單行程序了!是不是很酷!

我們先是一下perl是不是在這個(gè)軟件里面
我們?cè)谧烂嬗益I(其實(shí)在別處也可以)(在mac或者linux系統(tǒng)中就打開終端
選擇 Git Bash Here 這一項(xiàng)(沒有這一項(xiàng)就 徽標(biāo) + R調(diào)出運(yùn)行面板,在里面輸入C:\Program Files\Git\git-bash.exe

輸入 perl -h

perl幫助信息

可以看到這個(gè)軟件帶了perl程序,幫助里面列出來的這些參數(shù)是后來要說的,今天我們先看-e參數(shù)

Mac或Linux

Mac和Linux就干脆一些,它們自帶perl,所以不需要前期準(zhǔn)備

開始單行程序!

建議:后面的代碼最好你自己也輸入一下感受一下

我是用的Windows進(jìn)行演示的,在Mac和Linux上也是一樣的(終端
首先寫幾個(gè)示例代碼

例子

  • 示例1
perl -e 'print "Hello World!"'

# 輸出
Hello World!
  • 示例2
perl -e 'my $str = 'asdfghasd';$str =~ s/a/%/g;print "$str"'

# 輸出
%sdfgh%sd
  • 示例3
perl -e 'for(1..10){print "$_ "}'

# 輸出
1 2 3 4 5 6 7 8 9 10

發(fā)現(xiàn)規(guī)律沒,
perl -e ''
是他們的共同結(jié)構(gòu),其中關(guān)鍵的是-e參數(shù),它意思就是

在其后面的引號(hào)里面的東西當(dāng)作perl代碼來執(zhí)行。

這個(gè)豈不是不需要寫pl腳本就可以做很多事情了。是的,就是這樣,不過有些東西有些差別,以后再說。
你現(xiàn)在可以在-e后面的的引號(hào)(建議用單引號(hào),不然可能報(bào)錯(cuò),然后還會(huì)牽扯到其他問題)里面輸入perl代碼試一試。

用法

perl -e ' 代碼 '

問題

  • 換行

我想換行繼續(xù)輸入,按了一下回車,結(jié)果代碼直接執(zhí)行了。呃,尷尬,
單行程序和之前的寫在代碼編輯器里面的不一樣,假如我們想換行輸入代碼我們可以這樣做,
我們先不把引號(hào)對(duì)打全,只打出單個(gè),也就是這樣

perl -e '

繼續(xù)

perl -e 'my $str = "asdfghasd";

按一下回車輸入其他內(nèi)容

perl -e 'my $str = "asdfghasd";
$str =~ s/a/%/g;
print "$str";

最后加上末尾的引號(hào)
完整代碼為

perl -e 'my $str = "asdfghasd";
$str =~ s/a/%/g;
print "$str";'

# 輸出
%sdfgh%sd

有人可能會(huì)問,為什么不輸入 \ 符號(hào)來續(xù)行呢?
好,來試一試

perl -e 'my $str = "asdfghasd";\
$str =~ s/a/%/g;\
print "$str";'

# 輸出
Can't modify single ref constructor in substitution (s///) at -e line 2, near "s/a/%/g;"
Execution of -e aborted due to compilation errors.

出錯(cuò)了!因?yàn)橹罢f過了,在-e參數(shù)之后的引號(hào)內(nèi)東東都會(huì)被認(rèn)為是perl代碼,所以這個(gè)引號(hào)里面不能這么做,在引號(hào)外的命令被視為是shell的命令,在shell中的續(xù)行的方法就是在代碼換行之前輸入\ 然后再按下回車,就可以繼續(xù)輸入代碼了。

# shell代碼
echo 123 \
qwe \
asd
# 等價(jià)于
echo 123 qwe asd

# 輸出
123 qwe asd

既然有這種方式,能不能利用一下

perl -e '$n = 1;' \
-e 'print $n'

#輸出
1

這種方法利用輸入\ 實(shí)現(xiàn)了續(xù)行,但是我們可以看到 \ 是不在引號(hào)對(duì)之內(nèi),所以屬于shell命令。

注意:這里有兩個(gè)-e參數(shù),之后引號(hào)內(nèi)的內(nèi)容當(dāng)作perl命令執(zhí)行,同時(shí)還可以看到,看似我們使用兩個(gè)-e把程序打斷了,變量$n的內(nèi)容還被保存,沒有丟,但是一旦在執(zhí)行下一個(gè)perl命令的時(shí)候它就沒有了

perl -e '$n = 1;' \
-e 'print $n' \
| perl -e ' print "n is $n\n";'

# 輸出 
n is

變量$n是空的,所以在執(zhí)行一個(gè)perl內(nèi)的變量會(huì)暫時(shí)保存,但是一旦用管道隔開,變量就消失了,perl單行程序重新開始。

  • 引號(hào)

剛才前面說到了在-e參數(shù)后面要用''(單引號(hào)),最好不要用""(雙引號(hào)),不然shell中的變量和perl的變量會(huì)搞混

# shell中的變量
varname=123
# 然后在perl中聲明同樣名字的變量
perl -e "my $varname = 'asd';print $varname"

# 輸出
syntax error at -e line 1, near "my 123"
Execution of -e aborted due to compilation errors.

按照錯(cuò)誤說明,其實(shí)在聲明這個(gè)變量的時(shí)候就出錯(cuò)了,也就是perl外部變量與內(nèi)部變量的混淆了,為了避免這種事情發(fā)生,我建議使用單引號(hào)對(duì)。

如果偏要這么做的話也不是不行,那直接轉(zhuǎn)義咯!

varname=123
perl -e "my \$varname = 'asd';print \$varname"

# 輸出為
asd

但是實(shí)際上,使用雙引號(hào)你可能覺得可以進(jìn)行shell向perl傳遞變量。但是,每次使用perl自己的變量還要在 $ 前面加上 \ 來轉(zhuǎn)意,這太麻煩了!perl變量傳遞還有更好的做法,所以不推薦使用雙引號(hào)對(duì)。

后記

其實(shí)話說回來,One-Liners說的單行程序,一般來說的確就是寫在一行上面,也就是說代碼量不多的情況下,但其實(shí)有的時(shí)候還是有必要進(jìn)行換行的,那樣更容易修改和理清程序,這里其實(shí)是為了表明Perl是那種很能干的特質(zhì),就像在《Learning Perl》這本書里面說的那樣:

駱駝長(zhǎng)得也有點(diǎn)丑陋,但是它們努力工作,哪怕是在嚴(yán)酷的環(huán)境下也一樣不辭辛勞。駱駝能在種種不利的條件下幫你把事情搞定,盡管它長(zhǎng)相丑陋,氣味難聞,偶爾冷不丁的還對(duì)你吐上幾口口水。

補(bǔ)充

今天看《perl技術(shù)內(nèi)幕》突然發(fā)現(xiàn)還有一種命令行運(yùn)行perl代碼的方式

  • 用法
# 輸入perl之后,在后面寫上短橫線,然后換行
perl - 
代碼
# 最后使用__END__標(biāo)記來結(jié)束代碼
__END__

但是我發(fā)現(xiàn)這種方法無法接受管道的數(shù)據(jù)

更多

但是這本書都是介紹的一些小技巧,并沒有比較系統(tǒng)的說明各個(gè)參數(shù)之間的關(guān)聯(lián)以及各個(gè)參數(shù)的具體功能,但是當(dāng)你熟知這些參數(shù)之后回頭去看這本書會(huì)得到一定的啟發(fā)。


應(yīng)用

其實(shí)只是用這樣一個(gè)參數(shù)就可以干活了(因?yàn)?e后面的引號(hào)內(nèi)的東西作為perl代碼來執(zhí)行,也就是說某種程度上就是寫perl腳本)
例如

# 有一個(gè)文件123.txt
# 內(nèi)容為
Hello World!
--------------------------------------
# perl
perl -e '
open FILE,"<","123.txt" or die $!;
while(<FILE>){
    print $_;
}
'
--------------------------------------
# 輸出
Hello World!

再比如

cat 123.txt | perl -e '
while(<>){
    print $_;
}
'
--------------------------------------
# 輸出
Hello World!
'

但是實(shí)際上很多時(shí)候并不方便,僅僅使用-e參數(shù)孤掌難鳴,-e參數(shù)是一個(gè)大頭,也是必不可少的。俗話說的好,“一個(gè)好漢三個(gè)幫”,還需要搭配其他的參數(shù)來完成更加快捷簡(jiǎn)潔方便的方法來。
今天的-e參數(shù)就說到這里,后面還有更好玩的參數(shù)哦!我剛學(xué)perl單行程序,有哪些地方說錯(cuò)了請(qǐng)多多指教,多謝了!

我學(xué)習(xí)Perl單行程序的經(jīng)歷

剛開始看Perl的時(shí)候(那時(shí)候還沒有接觸編程的東西),我看到了老師寫了一些程序,于是想這個(gè)Perl到底是什么樣的語言,還可以在那種黑乎乎的東西(shell)里面這樣寫,當(dāng)時(shí)在網(wǎng)上查了一下各個(gè)參數(shù)的意思,剛開始不明白,想著這都是些什么玩意?。【桶压P記本丟到一邊去了。再后來,我看到了知乎的這個(gè)問題,突然想起來還有這個(gè)用法,然后慢慢的一邊看老師的代碼,一邊自己練習(xí)。慢慢的我就開始使用這門“獨(dú)門奇招”,談不上熟練,只是覺得好用,有時(shí)候覺得沒必要寫腳本就迫使自己寫單行程序,現(xiàn)在有時(shí)候不直接寫perl腳本,而是直接上perl單行程序搭配shell的工具使用。這篇博客中可能有錯(cuò)誤的地方,因?yàn)橛袝r(shí)候我是邊學(xué)邊寫的,希望大家能見諒。

之前一直覺得在新浪博客上寫不方便,現(xiàn)在把原文搬到簡(jiǎn)書上面了,稍微改了改,加了點(diǎn)內(nèi)容。

圖片來自UI制造者

版權(quán)聲明:本文采用 知識(shí)共享署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際許可協(xié)議 (CC BY-NC-ND 4.0) 進(jìn)行許可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,804評(píng)論 0 10
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,438評(píng)論 0 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,886評(píng)論 18 139
  • 本內(nèi)容來自某本書。 Chp1 Hello World! 本章是全書的第一章,本章會(huì)向你介紹開始學(xué)習(xí) Java 之前...
    sunnysans閱讀 538評(píng)論 0 1
  • 魚對(duì)水說:你看不見我的眼淚,因?yàn)槲以谒小?水對(duì)魚說;我能感覺到你的眼淚,因?yàn)槟阍谖倚闹小?魚對(duì)水說:我很寂寞,因...
    Thinker思白閱讀 733評(píng)論 0 0