perl一行式程序系列文章Perl一行式


对于Perl的一行式perl程序来说,选择要输出的、要删除的、要插入/追加的行是非常容易的事情,因为print/say决定行是否输出/插入/追加/删除。虽然简单,但对于广泛应用在sed的示例还是可以拿到这里来讨论一番。

因为输出/删除/插入/追加行都是通过print/say在不同条件下的操作,所以本文只会介绍输出操作,删除/插入/追加其实都是同样的原理。

输出第一行

$ perl -lne 'print;exit' file.log

输出第13行

$ perl -ne 'print if $. == 13' file.log

输出前10行

$ perl -ne 'print if $.<=10' file.log
$ perl -ne 'print if 1..10' file.log
$ perl -ne '$. <= 10 && print' file.log
$ perl -ne 'print; exit if $. == 10' file.log

输出最后一行

$ perl -ne '$last=$_;END{print $last}' file.log

或者通过文件结尾eof来判断:

$ perl -ne 'print if eof' file.log

这里的eof函数的作用是:如果下一行读取到了文件尾部eof,就返回1。否则

输出倒数10行

这个实现起来可能稍显复杂,但逻辑很简单:向一个数组中添加10行元素,如果数组元素个数超过了10,则剔除数组的第一个元素。

$ perl -ne '
push @lines,$_;
if(@lines>10){
shift @lines;
}
END{
print @lines
}
' /etc/passwd

这里是shift一个元素来保证"窗口"的稳定性:最多只有10个元素。另一种稳妥的方式是直接切片,从数组中取最后10个元素:

$ perl -ne '
push @lines,$_;
@lines = @lines[@lines-10..$#lines] if @lines>10;
END{print @lines}
' /etc/passwd

输出倒数第11行到倒数第2行

有了前一个示例作为基础,这个需求很容易实现。

保留一个11行元素的数组,最后输出前10个元素即可。

$ perl -ne '
push @a,$_;
shift @a if @a>11;
END{print @a[0..$#a-1]}
' /etc/passwd

输出文件的第偶数行

这个很简单,只需判断行号的奇偶性即可。

$ perl -ne 'print if $. % 2 == 0' file.log
$ perl -ne 'print unless $. % 2' file.log

输出能匹配的行

$ perl -ne 'print if /regexp/' file.log

输出两个匹配之间的行

$ perl -ne 'print if /regexp1/../regexp2/' file.log

输出匹配行的前一行

只需将每行保留到变量中,如果当前行匹配了,则输出上一行保存的值。

$ perl -ne '/regexp/ && $last && print $last;$last = $_' file.log

如果想要输出匹配的前M行,只需把这些数量的行保存到数组中,并不断地shift剔除就可以。

输出匹配行的后一行

$ perl -ne '$p && print; $p = /regexp/' file.log

Perl中正则表达式的匹配操作返回的是成功与否的布尔真假,所以$p = /regexp/表示如果匹配了,则$p的值为真,否则为假。

如果$p为真,则下一行将被输出,且继续对输出行进行匹配,如果输出行仍然能匹配,则继续输出下一行。

上面的过程可以改写成逻辑更为清晰的一行式:

$ perl -ne 'if($p){print;$p=0}++$p if /regexp/' file.log

上面的$p是一个状态标记变量,如果匹配成功,就标记为真值,并在输出的时候重置状态变量。

还可以采用另一种处理逻辑:自己编写从<>读取行的while循环,如果匹配了就继续读入下一行。因为读入的下一行可能继续匹配,所以在while循环中使用redo逻辑回到while循环的开头。

$ perl -se '
while(<>){
if(/$reg/){
if(eof){ exit; }
print $_ = <>;
}
redo if /$reg/;
}
' -- -reg="REGEXP" file.log

输出匹配行及其后5行

上面采用状态标记变量$p,这个状态标记变量可以更深入地使用。

如果匹配了,则$p设置为5,然后输出后面的行时对$p自减。

$ perl -ne '
if($p){print;$p--}
if(/regexp/){$p = 5;print};
' file.log

连续行去重

$ perl -ne '
next if "$line" eq "$_";
print $line = $_;
' file.log

Perl一行式:选择行输出、删除、追加、插入的更多相关文章

  1. Perl一行式:处理行号和单词数

    perl一行式程序系列文章:Perl一行式 所有行的行号 $ perl -pe '$_ = "$. $_"' file.log $ perl -ne 'print "$. ...

  2. Perl一行式:处理空白符号

    perl一行式程序系列文章:Perl一行式 假如文件file.log内容如下: root x 0 0 root /root /bin/bash daemon x 1 1 daemon /usr/sbi ...

  3. Perl一行式:字段处理和计算

    perl一行式程序系列文章:Perl一行式 获取每行最后一个字段 $ perl -alne 'print $F[$#F]' file.log 这里涉及到了选项"-a".数组@F.这 ...

  4. Perl一行式:文本编解码、替换

    perl一行式程序系列文章:Perl一行式 文本大小写转换 全部字符转换成大写或小写,有几种方式: # 转大写 $ perl -nle 'print uc' file.log $ perl -ple ...

  5. DataTables选择行并删除(删除单行)

    $(document).ready(function() { var table = $('#example').DataTable(); $('#example tbody').on( 'click ...

  6. winform代码:关联窗体数据更新,删除dataGridview中选中的一行或多行

    一.关联窗体数据更新 关联窗体数据修改时,如果一个为总体数据显示窗体A,另一个为详细修改窗体B,从A进入B,在B中对数据进行修改,然后返回A,这时A窗体的数据需要更新. 我采用最简单的方法,首先保证每 ...

  7. 在用easyui中做CRUD功能时,当删除一行或多行数据后再点击修改会提示你选中了多行,如何解决这个bug了?

    在用easyui中做CRUD功能时,当删除一行或多行数据后再点击修改会提示你选中了多行,如何解决这个bug了? 在删除成功后,加上这句话就可以了:$("#dg").datagrid ...

  8. Hadoop3集群搭建之——hive添加自定义函数UDTF (一行输入,多行输出)

    上篇: Hadoop3集群搭建之——虚拟机安装 Hadoop3集群搭建之——安装hadoop,配置环境 Hadoop3集群搭建之——配置ntp服务 Hadoop3集群搭建之——hive安装 Hadoo ...

  9. 删除dataGridview中选中的一行或多行

    一.实现的功能:可以删除一行或者多行数据,并在删除前提醒是否确定进行删除! DialogResult RSS = MessageBox.Show(this,"确定要删除选中行数据码?&quo ...

随机推荐

  1. 我理解的websocket

    短轮询:客户端发起请求,服务器无论有无消息都返回信息,结束http连接.然后继续发起请求. 长轮询:客户端发起请求,建立连接,直到服务端返回消息response,结束http连接.然后继续发起请求,重 ...

  2. 20175324 2018-2019-2 《Java程序设计》第8周学习总结

    本周学习<Java程序设计>第十五章: 泛型: 泛型(Generics)的主要目的是可以建立具有类型安全的集合框架,如链表.散列映射等数据结构. 泛型类声明:class 名称<泛型列 ...

  3. 20175324 2018-2019-2 《Java程序设计》第5周学习总结

    20175324 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 抽象类和具体类的区别在于抽象类中有抽象方法而具体类中没有.且抽象类不能实例化. 接口:如果一 ...

  4. kibana 创建index pattern 索引模式时过慢导致无法创建成功 以及解决方案

    下面我具体描述一下我遇到的问题. 在kibana上面创建索引点击创建时,一直显示下面的页面 就看到不停的在那转,始终创建不成功. 查看后台日志,看到状态码为403,报了如下的错误 由于我用的是es6版 ...

  5. Vue 过滤器的使用

    Vue官方文档是这样说的:Vue过滤器用于格式化一些常见的文本. 在实际项目中的使用: 定义过滤器 在src定义一个filter.js文件,里面定义过滤器函数,在最后要使用 exprot defaul ...

  6. go 使用 c接口

    在使用go语言时, 有时为了方便可以直接调用c语言的接口与库, 不需要重复编写. 那就来说说在go语言里面如何调用c的接口 首先编写好c语言的源文件与头文件,这里举一个简单的例子,实现一个字符串大小写 ...

  7. Java编程题: 写一个Singleton出来

    Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 一般Singleton模式通常有几种种形式: 第一种形式:  定义一个类,它的构造函数为private的, ...

  8. kibana研究

    概述 Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索.查看交互存储在Elasticsearch索引中的数据.它操作简单,基于浏览器的用户界面可以快速创建仪表板(das ...

  9. [Swift]LeetCode692. 前K个高频单词 | Top K Frequent Words

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  10. [Swift]LeetCode699. 掉落的方块 | Falling Squares

    On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th squ ...