为了账号安全,请及时绑定邮箱和手机立即绑定

如何获取与正则表达式匹配的第一行之后的文件部分?

/ 猿问

如何获取与正则表达式匹配的第一行之后的文件部分?

互换的青春 2019-12-09 11:17:55

我有一个约有1000行的文件。我想要文件的与我的grep语句匹配的行之后的部分。


那是:


$ cat file | grep 'TERMINATE'     # It is found on line 534

因此,我希望文件从535行到1000行进行进一步处理。


我怎样才能做到这一点?


查看完整描述

3 回答

?
手掌心

下面将打印匹配的行,TERMINATE直到文件末尾:


sed -n -e '/TERMINATE/,$p'

说明: 在执行脚本后-n禁用默认行为,即sed在每行上执行脚本后将其打印出来,-e指示脚本为sed,/TERMINATE/,$是地址(行)范围的选择,这意味着第一行与TERMINATE正则表达式(如grep)匹配的文件($) ,p是用于打印当前行的打印命令。


这将从 匹配行之后的行开始打印,TERMINATE直到文件末尾:(

从匹配行之后到EOF,不包括匹配行)


sed -e '1,/TERMINATE/d'

说明: 1,/TERMINATE/是地址(行)范围的选择,表示与TERMINATE正则表达式匹配的第一行输入的第一行,并且d是删除当前行并跳至下一行的delete命令。由于sed默认行为是打印行,因此它将在TERMINATE 输入结束之后打印行。


编辑:


如果您想在之前的行TERMINATE:


sed -e '/TERMINATE/,$d'

并且如果您希望TERMINATE一次通过两个不同文件中的前后两行:


sed -e '1,/TERMINATE/w before

/TERMINATE/,$w after' file

之前和之后文件将包含带有terminate的行,因此要处理每个文件,您需要使用:


head -n -1 before

tail -n +2 after

编辑2:


如果您不想对sed脚本中的文件名进行硬编码,则可以:


before=before.txt

after=after.txt

sed -e "1,/TERMINATE/w $before

/TERMINATE/,\$w $after" file

但是然后您必须转义$最后一行的含义,以便外壳程序不会尝试扩展$w变量(请注意,我们现在在脚本周围使用双引号而不是单引号)。


我忘了告诉新行在脚本中的文件名之后很重要,以便sed知道文件名结束。



编辑: 2016-0530


SébastienClément问:“如何TERMINATE用变量替换硬编码?”


您将为匹配的文本创建一个变量,然后以与前面的示例相同的方式进行操作:


matchtext=TERMINATE

before=before.txt

after=after.txt

sed -e "1,/$matchtext/w $before

/$matchtext/,\$w $after" file

在前面的示例中将变量用于匹配文本:


## Print the line containing the matching text, till the end of the file:

## (from the matching line to EOF, including the matching line)

matchtext=TERMINATE

sed -n -e "/$matchtext/,\$p"

## Print from the line that follows the line containing the 

## matching text, till the end of the file:

## (from AFTER the matching line to EOF, NOT including the matching line)

matchtext=TERMINATE

sed -e "1,/$matchtext/d"

## Print all the lines before the line containing the matching text:

## (from line-1 to BEFORE the matching line, NOT including the matching line)

matchtext=TERMINATE

sed -e "/$matchtext/,\$d"

在这些情况下,用变量替换文本的要点是:


[ ]中$variablename包含的变量()不会“扩展”,但[ ]中的变量会“扩展” 。因此,如果所有包含要用变量替换的文本,则必须将所有更改为。 single quotes'double quotes"single quotesdouble quotes

该sed范围也包含$并紧跟像字母:$p,$d,$w。他们也将像变量加以扩展,所以你要逃避这些$字符用反斜杠[ \],如:\$p,\$d,\$w。


查看完整回答
反对 回复 2019-12-09
?
慕婉清6462132

作为一个简单的近似值,您可以使用


grep -A100000 TERMINATE file

它会抓紧TERMINATE并在该行之后输出最多100000行。


从手册页


-A NUM, --after-context=NUM


匹配行后打印NUM行尾随上下文。 在连续的匹配组之间放置包含组分隔符(-)的行。使用-o或--only-matching选项,此选项无效,并给出警告。


查看完整回答
反对 回复 2019-12-09
?
芜湖不芜

在这里使用的工具是awk:


cat file | awk 'BEGIN{ found=0} /TERMINATE/{found=1}  {if (found) print }'

这是如何运作的:


我们将变量“找到”设置为零,评估为假

如果找到与正则表达式匹配的“ TERMINATE”,则将其设置为1。

如果我们的“找到”变量的值为True,请打印:)

如果您在非常大的文件上使用其他解决方案,则可能会占用大量内存。


查看完整回答
反对 回复 2019-12-09

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信