Linux 需要grep/awk/gawk返回整个部分,尽管有断线
我有以下问题。。。 我有一个类似于此的文件:Linux 需要grep/awk/gawk返回整个部分,尽管有断线,linux,awk,grep,find,gawk,Linux,Awk,Grep,Find,Gawk,我有以下问题。。。 我有一个类似于此的文件: 2018-04-25: line1 2018-04-25: line2 this is another line I'm a line 2018-04-25: line3 2018-04-25: line4 如果我运行:grep'this'test.log,结果将是: this is another line 但我需要的结果是: 2018-04-25: line2 this is anoth
2018-04-25: line1
2018-04-25: line2
this is another line
I'm a line
2018-04-25: line3
2018-04-25: line4
如果我运行:grep'this'test.log,结果将是:
this is another line
但我需要的结果是:
2018-04-25: line2
this is another line
I'm a line
因为“这是另一行”实际上是同一条记录的一部分,唯一的问题是我们在那里有一个换行符,我需要我的grep忽略这个换行符
- grep-C 1“this”test.log
- grep-b1“this”test.log
2018-04-25: line1
2018-04-25: line2
this is another line
I'm a line
2018-04-25: line3
2018-04-25: line4
您可以使用:grep-A2 line2 file.log
,它将返回:
2018-04-25: line2
this is another line
I'm a line
-A
代表上下文之后的,来自man:
-A num, --after-context=num
Print num lines of trailing context after each match.
或者,如果使用此
作为模式,则可以混合使用-B
和-a
,例如:
grep -B1 -A1 this file.log
这里有一种使用GNU awk的方法:行开头的日期是记录分隔符。对于包含模式的记录,打印上一个记录分隔符和当前记录
gawk -v RS='(^|\n)[0-9-]{10}' '
/this/ {sub(/^\n/, "", prev_RT); print prev_RT $0}
{prev_RT = RT}
' file
或者,更直接一些
awk '
function printif() {if (record ~ /this/) print record}
/^[0-9-]{10}/ {printif(); record = ""}
{record = (record ? record "\n" : "") $0}
END {printif()}
' file
对于给定的示例,这将起作用
$ gawk -v ORS= -v RS='2018-' '/this/{print RS $0}' ip.txt
2018-04-25: line2
this is another line
I'm a line
-v ORS=
清除输出记录分隔符
-v RS='2018-'
将2018-
设置为输入记录分隔符(假设所有记录的年份相同)
/this/{print RS$0}
如果记录包含this
,请打印记录分隔符和记录内容
另一个多行awk版本:
#!/usr/bin/awk -f
# When the line is starting with the time string
# a new record is starting...
/^[[:digit:]]{4}(-[[:digit:]]{2}){2}/ {
# Check if the (b)uffer matches /this/
if(b~/this/)
# ... and print it in that case
print b
# Empty the buffer in any case
b=""
}
# Append each line to the buffer
{b=b""ORS""$0}
它应该适用于任何版本的awk。为了完成此任务,我们还可以使用sed
以更隐秘的方式完成此任务:
sed -n '/[-0-9]\{10\}:/{x;/this/p;d};H;${x;/this/p}' <file>
grep
将起始行与-b1
隔开:
$ grep -B 1 "^ " file
2018-04-25: line2
this is another line
I'm a line
如果空间不够:grep-b1-v“^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}:“文件
从正则表达式匹配到另一个正则表达式:
awk '/line2/{f=1} f;/I\47m a line/{f=0}' file
2018-04-25: line2
this is another line
I'm a line
可能是RS=“\n2018-”
,这样可以避免记录条目本身包含2018-
@kvantour而不包含第一行的情况。。。有关稳健性,请参见glenn的答案。RS='(^ |\n)2018-“
将解决此问题。@karakfa需要更改打印stmt或处理RT。。。这将导致类似于格伦的答案:)我是故意尝试基于给定样本的更简单的答案;)不能真正使用A/B,因为行是可变的谁在这里投票?我看不出有什么原因。嗯,有一个通常的嫌疑犯。非常神秘的詹姆斯。想详细说明一下吗?@glennjackman是一位活跃的成员,他对所有他认为没有达到预期的问题都投了反对票。主要是脚本和shell工具相关的问题。嗯,我想惩罚回答者的“罪过”。艰苦的爱。哦,这是@nbari解决方案(++)的一个变体。
$ grep -B 1 "^ " file
2018-04-25: line2
this is another line
I'm a line
awk '/line2/{f=1} f;/I\47m a line/{f=0}' file
2018-04-25: line2
this is another line
I'm a line