bash - 如何过滤类似 grep 的搜索以要求 3 个字符串按给定的顺序和距离排列?
问题描述
我有一个文件,我想从中查看在有限的行范围内是否存在 3 个特定字符串。
第一个 2 总是一个接一个,第三个将是 #2 之后的 X 行。#3 也可以存在不止一次,但我只想要第一个。
例如
nope
nope
foo
bar
nope
nope
nope
nope
baz
nope
baz (ignore this one)
如果 foo 和 bar 一个接一个地存在并且 baz 在 100 行之内,我“赢”了。我怎样才能轻松实现这一目标?
现在我把它分解成许多小步骤,每当我找到“foo”时使用 grep -A100 (和其他 grep 东西)创建临时文件,然后检查它们是否有“bar”和“baz”。它有效,但它并不漂亮。
解决方案
根本不要grep
在这里使用:awk
是工作的正确工具。
awk -v range=100 '
BEGIN { matchedFoo = seenFoo = seenBar = (0 - range) }
/foo/ { seenFoo=NR }
/bar/ { if (seenFoo == NR-1) { seenBar=NR; matchedFoo=seenFoo; } }
/baz/ && (seenBar > (NR - range)) {
print("Matched foo@" matchedFoo ", bar@" seenBar ", baz@" NR);
exit(0);
}
'
...发射,您的样本输入:
Matched foo@3, bar@4, baz@9
...正确发出所需实例的行号。(当然,如果需要,除了数字之外,您还可以存储完整的字符串)。
简单说一下逻辑:
- 我们有单独的
seenFoo
和matchedFoo
变量的原因是foo
没有跟随的 newbar
不会改变输出中显示的行号。 - 我们初始化所有内容的原因
0 - range
是,这些值仍然是有效的整数(所以没有数学失败),而且baz
在输入的第一range
行中,a 没有看到值0
as 意味着第 0 行有匹配项bar
,并且因此在我们的 100 行搜索距离内。
推荐阅读
- r - 如何将时间序列日期转换为数据框日期
- python - PySpark:“/usr/libexec/java_home/bin/java:不是目录”(macOS Big Sur)
- typescript - 为什么将源文件夹添加到 Next.js 中的 tsconfig 包含部分时缺少类型定义
- python - 显示 sns distplot 上的所有 bin
- sql - 从混合层级中查找多个子级的第一个共同父级
- apache-spark - 尝试将字符串转换为 pyspark 数据帧中的 unix_timestamp 数据类型时出现 SparkUpgrade 异常
- java - 如何计算构成多边形中每个三角形的顶点?
- python - Python Pandas:从一组数字中获取两个最大值,但确保它们相隔 x 数量
- shopify - Shopify 节点后端-前端通信
- syntax - Isset 函数的语法