Perl One-Liners | Perl命令行学习1 -e参数

:本内容需要点的perl编程基础,最好是读过《perl语言入门》。

本系列是自己平常学习工作中的总结,每一个实例均为我为了讲解而设置的,自己试过的,如有错误,望能见谅

Perl 命令行参数 -e

perl One-Liners

说明

前言

之前在知乎上看到别人提问

“你见过哪些令你瞠目结舌的Perl代码技巧?” —— 有的人说是perl可以写诗,有的人就说是perl One-Liners。

Perl One-Liners简介

我一般就叫 Perl单行程序 ,那与平常写perl脚本有什么区别呢?

  • 平常写perl脚本
#!usr/bin/perl -w

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

看起来的确是简洁一些,但是实际上简练只是一方面,我的老师曾经说:

有的时候的确是简练,但更重要一点是 ——“流程化”

什么意思呢?其实按照shell编程来看,很多时候都是很多个工具相互搭配干活,中间用管道将他们哥几个串联起来,这样一前一后这种流程感是不是很强烈,有木有。就是知道干了什么事情,比较清晰明白。

例如某个流程是这样

cat读取文件到标准输入中
awk预处理
grep筛选
perl个性化处理
cat--->awk-->grep-->perl

同时,作为单行程序,在shell里面运行是可以利用到linux的工具的,也就是说perl也可以掺和进去,和里面的其他工具搭配干活的,比如cat,echo,ls,pwd,last,find,ps,parallel,sed,grep,awk等等好多工具。

对比之下有这样一些区别

  • 脚本需要写到文件中去然后才能运行,而单行命令的使用与其他命令行工具一样直接在终端或者shell中写代码或者直接复制之前的代码,之后运行就可以。
  • 单行程序可以搭配众多linux工具,使用管道串联起来,形成流程处理。而编写脚本虽然可以使用反引号或者system()或者exec()可以运行linux工具,但是流程感没有那么强烈。
  • 单行程序携带方便,比如在自己简书里面放一些代码,到别处只需要登陆简书复制代码就可以运行了。
  • 单行程序一前一后的流程并不是固定的,不同需求的情况下通过组合流程中的不同部分可以得到需要的结果,将所有处理的过程写到脚本中更改处理顺序不方便,当然也可以把perl单行写到脚本中然后参与shell的命令行的运行也是可以的。
  • 如果有的时候有些shell命令的用法你忘了,这个时候全部用perl命令行替代它的功能是可以的,就是说其实我感觉像是一些命令sedgrepawksortwc之类的命令的一些常见用法都可以用perl单行写出来,这样一来很多东西可以统一,但是可能不适用于单行而是适用于bash脚本了。

另外还有一点我忽略了,在沧浪之水v的博文《Perl programming and perl one line》里面提到了perl单行程序对于调试来说很方便,从而不需要IDE来。比如忘了某个函数的用法,你可以在单行里面直接开写,而不用写到文件里面,然后打开终端之后运行文件......

其实这样看来perl One-Liners有这么多好处,简练、流程化、可以搭配众多Linux大佬工具,那都用它得了。但是如果仅仅只是使用perl来完成所有的事情,那么将perl单行中的代码量增加很多,实际上写接近五十行代码的perl已经不适合用perl One-Liners了,因为在shell里面修改不方便,同时代码的保存也是问题。那个时候好不如写在脚本.pl文件里面了,同时对于使用较多模块,或者自己写包的形式就完全不适合用单行程序了。

打个比方,可能不太恰当,“perl单行程序就像是自行车,从家里哐当推出去骑着就跑;而写perl脚本就像是摩托车,从家里推车出来都要会儿时间,还得启动,有时候可能熄火;自行车最后跑起来那的确是没有摩托车快,也没有摩托车跑得远,但是它骑上去就开始跑了,轻便快捷,然后还有各种Linux工具的相互配合,进行接力!有时候胜过直接写perl脚本哦”。

perl单行 perl 脚本

好,废话少说。

在之前先做一下准备工作

首先你是用的是什么系统

Windows

说明:做生物信息学推荐使用linux,虽然现在windows 10下面有linux子系统,可能配置某些工具的时候会出点问题。因为我写文章习惯用我的笔记本写,所以我用Windows演示。不过没有关系,我下面的这些perl代码是跨平台的。

windows下没有包含perl的解释器,你需要先下载一个git for windows(不是github for windows)

或者下载一个完整版的cmder

这里推荐安装git for windows(虽然cmder完整版包含了git for windows,但是cmder使用的perl单行程序来说有些差别,就是在-e参数后面不能用单引号,需要用双引号,这与Linux和Mac上就有差别了,为了统一,就使用git for windows,然后在windows中的cmd中运行perl命令行程序,只能用双引号引起来,不方便后面的操作,没有Linux命令,不利于后续的使用)
安装好了之后,你会发现你的右键菜单多了点东西

  • Git GUI Here
  • Git Bash Here
右键菜单

如果没有这两个选项,就按照C:\Program Files\Git\git-bash.exe这个路径找

就我现在的理解(我刚用这个软件),就是相当于把linux的shell里面的命令搬到windows下面运行,同时也搬了perl的一些核心功能过来,所以我们就可以用这个软件来使用Linux下面的perl单行程序了!是不是很酷!

我们先是一下perl是不是在这个软件里面
我们在桌面右键(其实在别处也可以)(在mac或者linux系统中就打开终端
选择 Git Bash Here 这一项(没有这一项就 徽标 + R调出运行面板,在里面输入C:\Program Files\Git\git-bash.exe

输入 perl -h

perl帮助信息

可以看到这个软件带了perl程序,帮助里面列出来的这些参数是后来要说的,今天我们先看-e参数

Mac或Linux

Mac和Linux就干脆一些,它们自带perl,所以不需要前期准备

开始单行程序!

建议:后面的代码最好你自己也输入一下感受一下

我是用的Windows进行演示的,在Mac和Linux上也是一样的(终端
首先写几个示例代码

例子

  • 示例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

发现规律没,
perl -e ''
是他们的共同结构,其中关键的是-e参数,它意思就是

在其后面的引号里面的东西当作perl代码来执行。

这个岂不是不需要写pl脚本就可以做很多事情了。是的,就是这样,不过有些东西有些差别,以后再说。
你现在可以在-e后面的的引号(建议用单引号,不然可能报错,然后还会牵扯到其他问题)里面输入perl代码试一试。

用法

perl -e ' 代码 '

问题

  • 换行

我想换行继续输入,按了一下回车,结果代码直接执行了。呃,尴尬,
单行程序和之前的写在代码编辑器里面的不一样,假如我们想换行输入代码我们可以这样做,
我们先不把引号对打全,只打出单个,也就是这样

perl -e '

继续

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

按一下回车输入其他内容

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

最后加上末尾的引号
完整代码为

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

# 输出
%sdfgh%sd

有人可能会问,为什么不输入 \ 符号来续行呢?
好,来试一试

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.

出错了!因为之前说过了,在-e参数之后的引号内东东都会被认为是perl代码,所以这个引号里面不能这么做,在引号外的命令被视为是shell的命令,在shell中的续行的方法就是在代码换行之前输入\ 然后再按下回车,就可以继续输入代码了。

# shell代码
echo 123 \
qwe \
asd
# 等价于
echo 123 qwe asd

# 输出
123 qwe asd

既然有这种方式,能不能利用一下

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

#输出
1

这种方法利用输入\ 实现了续行,但是我们可以看到 \ 是不在引号对之内,所以属于shell命令。

注意:这里有两个-e参数,之后引号内的内容当作perl命令执行,同时还可以看到,看似我们使用两个-e把程序打断了,变量$n的内容还被保存,没有丢,但是一旦在执行下一个perl命令的时候它就没有了

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

# 输出 
n is

变量$n是空的,所以在执行一个perl内的变量会暂时保存,但是一旦用管道隔开,变量就消失了,perl单行程序重新开始。

  • 引号

刚才前面说到了在-e参数后面要用''(单引号),最好不要用""(双引号),不然shell中的变量和perl的变量会搞混

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

按照错误说明,其实在声明这个变量的时候就出错了,也就是perl外部变量与内部变量的混淆了,为了避免这种事情发生,我建议使用单引号对。

如果偏要这么做的话也不是不行,那直接转义咯!

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

# 输出为
asd

但是实际上,使用双引号你可能觉得可以进行shell向perl传递变量。但是,每次使用perl自己的变量还要在 $ 前面加上 \ 来转意,这太麻烦了!perl变量传递还有更好的做法,所以不推荐使用双引号对。

后记

其实话说回来,One-Liners说的单行程序,一般来说的确就是写在一行上面,也就是说代码量不多的情况下,但其实有的时候还是有必要进行换行的,那样更容易修改和理清程序,这里其实是为了表明Perl是那种很能干的特质,就像在《Learning Perl》这本书里面说的那样:

骆驼长得也有点丑陋,但是它们努力工作,哪怕是在严酷的环境下也一样不辞辛劳。骆驼能在种种不利的条件下帮你把事情搞定,尽管它长相丑陋,气味难闻,偶尔冷不丁的还对你吐上几口口水。

补充

今天看《perl技术内幕》突然发现还有一种命令行运行perl代码的方式

  • 用法
# 输入perl之后,在后面写上短横线,然后换行
perl - 
代码
# 最后使用__END__标记来结束代码
__END__

但是我发现这种方法无法接受管道的数据

更多

但是这本书都是介绍的一些小技巧,并没有比较系统的说明各个参数之间的关联以及各个参数的具体功能,但是当你熟知这些参数之后回头去看这本书会得到一定的启发。


应用

其实只是用这样一个参数就可以干活了(因为-e后面的引号内的东西作为perl代码来执行,也就是说某种程度上就是写perl脚本)
例如

# 有一个文件123.txt
# 内容为
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!
'

但是实际上很多时候并不方便,仅仅使用-e参数孤掌难鸣,-e参数是一个大头,也是必不可少的。俗话说的好,“一个好汉三个帮”,还需要搭配其他的参数来完成更加快捷简洁方便的方法来。
今天的-e参数就说到这里,后面还有更好玩的参数哦!我刚学perl单行程序,有哪些地方说错了请多多指教,多谢了!

我学习Perl单行程序的经历

刚开始看Perl的时候(那时候还没有接触编程的东西),我看到了老师写了一些程序,于是想这个Perl到底是什么样的语言,还可以在那种黑乎乎的东西(shell)里面这样写,当时在网上查了一下各个参数的意思,刚开始不明白,想着这都是些什么玩意啊!就把笔记本丢到一边去了。再后来,我看到了知乎的这个问题,突然想起来还有这个用法,然后慢慢的一边看老师的代码,一边自己练习。慢慢的我就开始使用这门“独门奇招”,谈不上熟练,只是觉得好用,有时候觉得没必要写脚本就迫使自己写单行程序,现在有时候不直接写perl脚本,而是直接上perl单行程序搭配shell的工具使用。这篇博客中可能有错误的地方,因为有时候我是边学边写的,希望大家能见谅。

之前一直觉得在新浪博客上写不方便,现在把原文搬到简书上面了,稍微改了改,加了点内容。

图片来自UI制造者

版权声明:本文采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,734评论 0 10
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,378评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,638评论 18 139
  • 本内容来自某本书。 Chp1 Hello World! 本章是全书的第一章,本章会向你介绍开始学习 Java 之前...
    sunnysans阅读 511评论 0 1
  • 鱼对水说:你看不见我的眼泪,因为我在水中。 水对鱼说;我能感觉到你的眼泪,因为你在我心中。 鱼对水说:我很寂寞,因...
    Thinker思白阅读 707评论 0 0