[英]How to get lines between two patterns
我有一个像这样的文件:
sth1
某事
b sth3
b sth4
第5部
第6
第6
d sth8
d sth9
d sth10
X sth10
X sth11
我想重新获得以b
开头的第一行和以d
开头的最后一行之间的所有行:
b sth3
b sth4
第5部
csth6
csth6
d sth8
d sth9
d sth10
我有一个sed命令sed -n /"b"/,/"d"/p final.txt
但是输出是:
b sth3
b sth4
第5部
csth6
csth6
d sth8
我的问题是如何修改sed命令以获得预期结果?
对不起,蜜蜂不准确。 我应该问一下:
我有一个像这样的文件:
127.0.0.1--[2014年6月4日:11:21:01 +0200] STH1
127.0.0.1--[2014年6月4日:11:21:01 +0200] STH2
127.0.0.1--[2014年6月4日:11:21:01 +0200] STH3
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH4
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH5
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH6
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH7
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH8
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH9
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH10
127.0.0.1--[2014年6月4日:14:21:01 +0200] STH11
127.0.0.1--[2014年6月4日:14:21:01 +0200] STH12
127.0.0.1--[2014年6月4日:15:21:01 +0200] STH13
127.0.0.1--[2014年6月4日:15:21:01 +0200] STH14
我想在包含$startDate="04/Jun/2014:12:21:01"
第一行和包含$endDate="04/Jun/2014:13:21:01"
最后一行之间提取内容。 结果应为:
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH4
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH5
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH6
127.0.0.1--[2014年6月4日:12:21:01 +0200] STH7
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH8
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH9
127.0.0.1--[2014年6月4日:13:21:01 +0200] STH10
$startDate
和$endDate
是BASH脚本中的变量。 我为上一个帖子提出的确切问题表示歉意...
如果您的文件已经按第一列( a, b, c...
)排序,则适用于您的示例:
awk '$1>="b"&&$1<="d"' file
这里的"b"
和"d"
可以是其他字符串,例如abc
和zzz
,只要文件已排序,它就可以工作。
根据您的示例,此sed行在这里起作用:
sed -n '/^b/,/^d/{/^[^d]/p};/^d/p' file
这是您可以在awk
完成的一种方法:
awk '/^b/{p=1} /^d/{p=2} p==2 && substr($1, 1, 1) != "d" {exit} p' file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
这是一个awk
awk '/^b/ {f=1} /^d/ {g=1} g && !/^d/ {f=0} f' file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
使用此sed命令可获得预期的结果。
$ sed -n '/^b/,/^d/{p;d};/^d/p' `input_filename`
如果文件未排序,则必须循环两次:首先知道要打印的行,然后再打印它们:
$ awk 'FNR==NR {if (/^b/ && !b) {b=NR} if (/^d/) {d=NR}; next} (FNR>=b && FNR<=d)' file file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
根据注释,如果要将b
和d
定义为参数,可以使用:
-v start="your_start_date"
-v end="your_end_date"
查看带有当前数据的示例:
$ awk -v start="b" -v end="d" 'FNR==NR {if ($1 == start && !b) {b=NR} if ($1 == end) {d=NR}; next} (FNR>=b && FNR<=d)' file file
b sth3
b sth4
c sth5
c sth6
c sth6
d sth8
d sth9
d sth10
根据您的最新更新:
$ startDate="04/Jun/2014:12:21:01"
$ endDate="04/Jun/2014:13:21:01"
$ awk -v start="$startDate" -v end="$endDate" 'FNR==NR {if ($0 ~ start && !b) {b=NR} if ($0 ~ end) {d=NR}; next} (FNR>=b && FNR<=d)' file file
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH4
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH5
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH6
127.0.0.1 - - [04/Jun/2014:12:21:01 +0200] STH7
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH8
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH9
127.0.0.1 - - [04/Jun/2014:13:21:01 +0200] STH10
如果您不介意grep
:
grep "^[b-d]" file
sed -n '/^b/p;/^c/p;/^d/p' YourFile
假设它有点像您的样本。 照顾b
或d
的遗漏行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.