我希望获取所有包含“search_string”一词的行+其后的行+其前匹配“mod”的行。
我试过:
grep -n 'mod\|search_string' ip | grep --before 1 search_string> inter
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op
有没有更好的办法?
文件:
mod start1
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5
预期输出:
mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too
答案1
awk '
$0 ~ /mod/ { md=$0 }
$0 ~ /search_string/ { if(md!="") { print md }; md="" ; print; getline; print }
'
解释:
- 包含的行
mod
另存为md
. search_string
包含触发打印先前保存的行md
、该行本身和下一行的行。if(md!="")
并md=""
确保当单个(在您的示例中)下mod
有多个 -s 时不会出现重复行。search_string
mod
mod start3
笔记:
mod
包含和的行将search_string
打破这个逻辑。
答案2
您的文件包含“回车”字符。最好在 Unix 中删除它们。要打印您发布的命令序列(删除回车符),请尝试:
awk '{gsub(/\r/,"")}
/mod/ { a = $0 }
/search_string/{ if(a!=""){print(a);a=""}
print;getline;print
}
' infile
或者作为一句单行:
$ awk '{gsub(/\r/,"")}/mod/{a=$0}/search_string/{if(a!=""){print(a);a=""}print;getline;print}' infile
mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too
由于可以在 (GNU) awk 中使用多字符记录分隔符,我们可以将记录分隔符设置为mod
并仅打印包含search_string
.需要 printf 来重建原始记录。
要打印您发布为“预期输出”的内容,请尝试:
awk '/search_string/{printf("mod%s", $0)}' RS=mod infile
答案3
如果您想在 Python 脚本中执行此操作:
# Read file into memory.
with open('myfile.txt') as f:
lines = [line.rstrip() for line in f]
# Loops through lines backwards, looking for string and optionally mod.
output_lines = list()
find_mod = False
for i, line in enumerate(lines[::-1]):
if 'search_string' in line:
output_lines.append(lines[::-1][i-1])
output_lines.append(lines[::-1][i])
find_mod = True
elif find_mod and 'mod' in line:
output_lines.append(lines[::-1][i])
find_mod=False
print("\n".join(output_lines[::-1]))