Perl One-Liners | Perl命令行學(xué)習(xí)2 -p和-n參數(shù)

Perl 命令行參數(shù) -p和-n

【上集回顧】
上一次提到了-e參數(shù)皮服,一般在使用perl的單行程序時都會加上-e參數(shù)别凹。-e參數(shù)就是將后面引號內(nèi)的內(nèi)容當(dāng)作perl代碼執(zhí)行篷店。

這一次來說一說另外兩個常見的-p和-n參數(shù)砂客,這兩個參數(shù)與輸入輸出相關(guān)

簡介

-p:將參數(shù)當(dāng)作文件讀取進來挤牛,并且每次讀取一行遍歷文件预鬓,并把執(zhí)行-e參數(shù)之后的perl代碼部分得到默認(rèn)變量$_打印到標(biāo)準(zhǔn)輸出中(可以是屏幕也可以進入管道)。

-n:將參數(shù)當(dāng)作文件讀取進來赊颠,并且每次讀取一行遍歷文件格二。

兩個看起來共性有點大,那有什么區(qū)別呢竣蹦?

在之前先來看一個例子吧顶猜!

例子

首先新建一個文件 123.txt

里面的內(nèi)容為

the string is hello
the number is 12345
the float is 1.2345

我怎么知道是不是逐行讀取的呢?

123.txt所在位置右鍵痘括,打開git bash here或者打開終端cd到當(dāng)前目錄

輸入

perl -n -e '++$n;print "$n  $_"' 123.txt

# 輸出為

1  the string is hello
2  the number is 12345
3  the float is 1.2345

可以看到程序部分執(zhí)行了三次长窄,文件是逐行讀取的

-p參數(shù)

  • 示例1
# 比如我想讓含有字符串string的行打印出來
perl -p -e 'm/string/' 123.txt

# 輸出為
the string is hello
the number is 12345
the float is 1.2345

可以看到和原來的文件是沒有什么兩樣的

  • 示例1.1
perl -p -e 's/string/number/' 123.txt

# 輸出
the number is hello
the number is 12345
the float is 1.2345

第一行和之前的結(jié)果不一樣了

但是假如說我想的是“只要那些有string這樣字眼的行輸出出來呢”滔吠?

于是我就想可不可以這樣寫:

  • 示例2
perl -p -e 'if(m/string/){print $_}' 123.txt

# 輸出為
the string is hello
the string is hello
the number is 12345
the float is 1.2345

可以看到文件第一行輸出了兩次,也就是說

-p參數(shù)不管你的代碼中有什么判斷語句來控制輸出挠日,每讀取一行都會輸出一下$_疮绷,這個與代碼中的print不會合并,它不管究竟有沒有print

那它是輸出的什么呢嚣潜,輸出什么時候的$_呢冬骚?

來這樣玩一下

  • 示例3
perl -p -e 's/string/number/;s/hello/world/' 123.txt

# 輸出為
the number is world
the number is 12345
the float is 1.2345

傳進來文件第一行的變量$_在perl代碼中其實變換了兩次

最開始時候:the string is hello
第一次變換:the number is hello
第二次變化:the number is world

可以看到,-p參數(shù)每次輸出的$_的值是它從代碼執(zhí)行最后的值

再來調(diào)戲一下$_;

  • 示例4
perl -p -e 'if(m/string/){$_ = "foo\n"}' 123.txt

# 輸出為
foo
the number is 12345
the float is 1.2345

第一行已經(jīng)變了懂算,就是說$_是可以被改變只冻,甚至改變巨大都可以

那為了剛才我們的目標(biāo),可以這樣

  • 示例5
# 如果不能匹配到 string 就將變量$_設(shè)置為空字符串计技,類似于清空 
perl -p -e 'if(!m/string/){$_ = ""}' 123.txt

# 輸出為
the string is hello

哈哈喜德!沒難倒我們!達到目標(biāo)了垮媒!

你有沒有感覺不太好呢舍悯!這里判斷條件倒是很簡單,所以可以這樣做睡雇,假如判斷條件多了萌衬,代碼量多了,每次都要這樣來思考不是有點不順嗎入桂?

這樣吧奄薇,開門見山驳阎,有請-n參數(shù)登場

-n參數(shù)

先來按照-p的路子試一試-n

  • 示例6
# 我想要的是將含有string字符串的行打印出來
perl -n -e 'm/string/' 123.txt

# 輸出為:

是的抗愁,什么都沒有,的確是這樣呵晚,不是我碼字把它碼掉了.

其實有了上面的-p的說明蜘腌,這里-n已經(jīng)比較明確了,它其他方面的和-p一樣饵隙,但是他不會輸出$_撮珠,也就是說程序默認(rèn)不會輸出任何東西(當(dāng)然不包括錯誤信息在內(nèi))

于是上面的問題就可以這樣解了

  • 示例7
perl -n -e 'if(m/string/){print $_}' 123.txt

輸出為:
the string is hello

到了這里大家應(yīng)該明白了-p和-n的區(qū)別,其實對于命令行來說金矛,-p和-n用的都挺多的芯急,就看你需要什么,怎么做起來更快驶俊,就選哪一個娶耍。

問題

  1. 假如我讀取文件不想要后面的換行符出現(xiàn),輸出的時候我自己加換行符饼酿,怎么做榕酒?

答:其實和寫perl腳本一樣胚膊,其實可以這樣做

perl -n -e 'chomp;if(/string/){print "$_\n"}' 123.txt

也就是加一個chomp;
其實除了這種方式,還有一種加上參數(shù)-l可以達到先自動chomp想鹰,之后自動在$_后面加上\n然后輸出

  1. 這個-p和-n參數(shù)的每行讀取文件怎么和那個鉆石操作符<>一樣拔赏瘛!

答:的確是這樣的

# 平常寫perl腳本我們一般寫
open READ,"<","123.txt" or die "$!";
while(< READ >){
    ..........;
}

# 對于單行程序直接就是
perl -n -e '........' 123.txt

這樣看來單行程序在寫較短程序上比直接去寫perl腳本來的快辑舷,來的節(jié)省

在這里再引申一下

如果我有一個fasta文件喻犁,假設(shè)名稱為fasta.fasta 內(nèi)容為

>cox1
ATGCGATCGTAGCATGCTAGCTACG
ACAAGCTAGCTAGCTAGCAGCATCT
ACGTGCAT
>rpl10
ATGAGCTAGCTAGCTAGACGTACGT
ACGTAG

# 假如在命令行中這樣輸入
perl -p -e 'if(/^>/){$_ = <> || ""}' fasta.fasta

# 輸出為
ATGCGATCGTAGCATGCTAGCTACG
ACAAGCTAGCTAGCTAGCAGCATCT
ACGTGCAT
ATGAGCTAGCTAGCTAGACGTACGT
ACGTAG
  1. 為什么我一直沒有輸出啊惩妇!

你是不是把參數(shù)順序?qū)懛戳?/p>

  • 錯誤寫法
    perl -e -p 'print if /string/' 123.txt
    perl -e -n 'print if /string/' 123.txt
    perl -ep 'print if /string/' 123.txt
  • 正確寫法
    perl -p -e 'print if /string/' 123.txt
    perl -pe 'print if /string/' 123.txt

第三種情況雖然兩個參數(shù)并在一起寫了株汉,可是有先后順序,其實第三種就是第一種的寫法歌殃。也就是說引號對引起來的代碼需要靠近-e乔妈,而且-e參數(shù)一般放在所有參數(shù)最后一個

perl讀取文件的方式

  • 放在命令行代碼塊的末尾
perl -n -e 'print $_' 123.txt
  • 結(jié)合Linux工具
cat 123.txt | perl -n -e 'print $_'
  • 使用文件句柄
perl -e '
open FILE,"<","123.txt" or die $!;
while(<FILE>){
    print $_;
}
'

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末氓皱,一起剝皮案震驚了整個濱河市路召,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌波材,老刑警劉巖股淡,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異廷区,居然都是意外死亡唯灵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門隙轻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埠帕,“玉大人,你說我怎么就攤上這事玖绿×泊桑” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵斑匪,是天一觀的道長呐籽。 經(jīng)常有香客問我,道長蚀瘸,這世上最難降的妖魔是什么狡蝶? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮贮勃,結(jié)果婚禮上贪惹,老公的妹妹穿的比我還像新娘。我一直安慰自己衙猪,他們只是感情好馍乙,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布布近。 她就那樣靜靜地躺著,像睡著了一般丝格。 火紅的嫁衣襯著肌膚如雪撑瞧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天显蝌,我揣著相機與錄音预伺,去河邊找鬼。 笑死曼尊,一個胖子當(dāng)著我的面吹牛酬诀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骆撇,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瞒御,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了神郊?” 一聲冷哼從身側(cè)響起肴裙,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涌乳,沒想到半個月后蜻懦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡夕晓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年宛乃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒸辆。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡征炼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吁朦,到底是詐尸還是另有隱情柒室,我是刑警寧澤渡贾,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布逗宜,位于F島的核電站,受9級特大地震影響空骚,放射性物質(zhì)發(fā)生泄漏纺讲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一囤屹、第九天 我趴在偏房一處隱蔽的房頂上張望熬甚。 院中可真熱鬧,春花似錦肋坚、人聲如沸乡括。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诲泌。三九已至盲赊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敷扫,已是汗流浹背哀蘑。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葵第,地道東北人绘迁。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像卒密,于是被迫代替她去往敵國和親缀台。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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