【问题标题】:egrep AND condition on multiple patterns not working [closed]egrep AND 多个模式的条件不起作用[关闭]
【发布时间】:2021-01-10 15:59:17
【问题描述】:

egrep AND 条件无法使用以下命令处理日志文件:

我的命令是:

egrep -E "20-Sep-20|^[ ]*|^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT" file.log

结果:

20 年 9 月 21 日 14:30:40.223 调试 6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT 准备 - ************** 结束 ***************
20 年 9 月 21 日 14:30:40.223 信息 6f0747e47829 QzAJ7ru4ayOWqRm
oMXskCaN0RWrdfT 准备 - 数据准备步骤
已结束
**** 20 年 9 月 21 日 14:30:40.273 信息 6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT prep - 依赖步骤已完成 使用 step_id = 9l2CDtSl2ZmTOUk 21-Sep-20 14:30:40.439 信息删除
6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT 准备 - 分步运行 完成:成功=真 20 年 9 月 22 日 14:30:40.500 信息 6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT prep - 依赖步骤已完成 使用 step_id = 9l2CDtSl2ZmTOUk 22-Sep-20 14:30:40.560 信息删除
6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT 准备 - 分步运行 完成:成功=真 20 年 9 月 22 日 14:30:40.600 错误 6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT- Traceback(最近一次通话最后):
文件 “/usr/local/lib/python3.7/site-packages/wiz_task/tasks/modeling/py_module.py”, 第 55 行,在 run_py_module 中 (成功,报告)= instance.execute(project_id,process_id,module_name,step_name,run_params,**kwargs)文件 "/code/test_module/domkar/py_code/python-attributor/attributor/module.py", 第 62 行,在执行中 model2_out.main() 文件“/code/test_module/domkar/py_code/python-attributor/attributor/model/model2.py”, 第 883 行,主要 model_constr,FixedCoeffTable,planner,Output_data=self.model () 文件 "/code/test_module/domkar/py_code/python-attributor/attributor/model/model2.py", 第 503 行,模型中 model_constr_res = model_constr_worker.runSingleModel (cmodel_trfm_data_ref, model_constr, False) 文件 "/code/test_module/domkar/py_code/python-attributor/attributor/lib/algo/model_worker.py", 第 1283 行,在 runSingleModel model_result = self.runMixedModel(数据,模型,light_mode)文件“/code/test_module/domkar/py_code/python-attributor/attributor/lib/algo/model_worker.py”, 第 625 行,在 runMixedModel 返回self.runLinearModel(数据,模型,light_mode)文件“/code/test_module/domkar/py_code/python-attributor/attributor/lib/algo/model_worker.py”, 第 597 行,在 runLinearModel result.setRetention (DataUtility.retention (data, dep_var, date_var, fixed_vars, model.getHierarchyVars ()) ) 文件 "/code/test_module/domkar/py_code/python-attributor/attributor/lib/data/data_utility.py", 第 396 行,保留 aaaaaaaaaaaaaaaaaaaa NameError: name 'aaaaaaaaaaaaaaaaaaaa' is not defined 23-Sep-20 14:30:40.439 INFO 6f0747e47829 QzAJ7ru4ayOWqRm oMXskCaN0RWrdfT prep - 步骤运行已完成:success=True

预期结果:

当给定一个无效的字符串(模式)AND条件失败并仍然返回结果但我需要空结果。因为给定的模式与文件不匹配。

【问题讨论】:

  • 噗,请花时间重新格式化您的帖子。请用前导 4 个空格发布输入和输出以及命令 - 前导 4 个空格使其显示为在代码块中,格式正确。
  • 要通过缩进将输入和输出格式化为代码,您可以选择要格式化的代码并使用编辑器字段的{} 工具。或者,您可以将~~~ 单独放在代码块之前和之后的一行中。这样你就不需要缩进了。我以您的命令行为例。
  • 您能准确解释您要匹配的内容吗?实际上,由于第二个 OR'ed 子模式,您的模式将匹配所有内容(^[ ]* 匹配行首的任意数量的非空格字符,包括零)
  • 请检查并修复问题中显示的输出。在其他人进行编辑后,换行符似乎不正确。复制粘贴并重新格式化可能会更容易。
  • @Pikrass 我正在尝试获取两个日期之间的所有行,并在两个模式上使用 AND 条件。我不确定我在做什么错。如果我不使用日期过滤器,我最终会丢失其间的多行。所以,我希望这些日期过滤器之间的所有行都带有匹配模式的 AND 条件。

标签: linux ubuntu unix grep


【解决方案1】:

根据您的评论,您正在尝试匹配两个模式之间的所有行。这对于 grep 是不可能的,因为 grep 逐行工作。您可以匹配一行,但到下一行时,grep 无法仅根据它之前是否匹配来知道它是否应该匹配。

您所做的不是“与条件”,我无法理解您的意思。 Perl 正则表达式有一种“AND”子句(称为前瞻),但它的意思是“此时,下一个字符应该匹配这个模式和另一个模式”(前瞻比那个更微妙但我正在简化)。没有办法将其用于您想要的。

为了学习,我们来分析一下你的模式:

20-Sep-20|^[ ]*|^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT

| 字符表示“”。因此,您正在匹配与以下 3 种模式中的 任一 匹配的任何行:

20-Sep-20
^[ ]*
^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT

第二个模式的意思是“任何非空格字符在一行的开头任意次数(包括零)”。这符合一切。因此 grep 将匹配您输入的每一行,并按原样输出。


你真正想要的是“匹配这一行,后跟任意数量的字符(包括换行符),然后是这一行”。没有“AND”,这是一个单一的模式。但是需要同时应用于多行,而grep做不到。

但是,使用其他程序可以做到这一点。下面是一个 awk 的例子:

awk '/20-Sep-20/ { a=1 } ; { if (a == 1) print } ; /^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT/ { exit }' file.log

我在这里做的是逐句声明:

  • 在匹配“20-Sep-20”的行上,我将变量“a”设置为 1。
  • 在所有行中,如果“a”为 1,则打印该行
  • 在线匹配“^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT”,退出(因此停止打印)

如果第二个模式不匹配,命令不应返回任何内容,我看到的最明显的解决方案是首先对其进行 grep,然后仅在匹配时执行 awk。

end_pattern='^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT'
grep -qE "$end_pattern" file.log && awk "/20-Sep-20/ { a=1 } ; { if (a == 1) print } ; /$end_pattern/ { exit }" file.log

如果在第一个模式之前找到第二个模式,这将不起作用。

我看到实现此目的的另一种完全不同的方法是使用 grep 选项“-n”对开始行和结束行进行 grep 以获取行号,然后使用 head 和 tail(或 sed)来获取范围(如果两者模式匹配,结束 > 开始)。

第三种方法是使用支持多行正则表达式的编程语言。

【讨论】:

  • 我按照你的建议用 awk 尝试了上述方法,但是当我尝试给出错误的模式时,它应该返回空结果。
  • 在线匹配 "^[ ]*21-Sep-20.*6f0747e47829.*oMXskCaN0RWrdfT",退出(因此它停止打印)——如果我通过错误的模式代替 6f0747e47829 或 oMXskCaN0RWrdfT ,它仍然给我结果,它应该是一个空文件,因为模式不匹配
【解决方案2】:

让我给你一个一般性的答案:grep中如何创建逻辑表达式?

  • 或者可以用grep -E "cond1|cond2"处理
  • AND 可以用grep "cond1" | grep "cond2" 处理

所以如果你想 grep,比如说cond1 AND (cond2 OR cond3),你需要这样的东西:

grep "cond1" | grep -E "cond2|cond3"

所以,请编辑您的问题并清楚地解释条件及其逻辑关系。

此外,正如答案和 cmets 中所解释的:^[ ]* 表示您的行可能以空格开头(基本上每行都如此),所以不要再使用它了。

评论后编辑

以您的情况为例:假设您想查看 9 月 20 日或 9 月 21 日的条目,他们都必须包含字符串 "oMXskCaN0RWrdfT",您可以执行以下操作:

grep -E "20-Sep-20|21-Sep-20" file.log | grep "oMXskCaN0RWrdfT"

【讨论】:

  • 感谢您的明确解释。我需要的是来自我发布的日志文件示例的内容,我需要与 AND 条件上的模式匹配的行以及这些匹配模式之间的行。但我最终错过了我需要的两行之间。
  • @90's_jaddu:我根据你的评论编辑了我的答案,这是你要找的吗?
猜你喜欢
  • 2016-06-28
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2014-05-15
  • 2020-09-06
  • 1970-01-01
相关资源
最近更新 更多