【问题标题】:Egrep acts strange with -f option使用 -f 选项时 Egrep 的行为很奇怪
【发布时间】:2009-03-06 15:06:25
【问题描述】:

我有一个奇怪的egrep -f

例子:

$ egrep -f ~/tmp/tmpgrep2 orig_20_L_A_20090228.txt | wc -l
3
$ for lines in `cat ~/tmp/tmpgrep2` ; do  egrep $lines orig_20_L_A_20090228.txt ; done | wc -l
12

谁能给我一个提示可能是什么问题? 不,文件在执行之间没有改变。 egrep 行数的预期答案是 12。

文件内容更新:搜索到的文件包含 cca 13000 行,每行 500 字符长,模式文件包含 12 行,每行 24 字符长。该模式始终(且仅)出现在搜索文件 (26-49) 中的固定位置。

模式内容更新:tmpgrep2 中的每个模式都是一个 24 字符长的数字。

【问题讨论】:

  • 上次退出的日期/时间行是您的命令行提示符吗?如果是这样,我建议将您在问题中转录的内容限制为“$”(对于 bash 等)或“%”(对于 C shell)或“#”(如果您以 root 身份工作)。

标签: linux shell resultset grep


【解决方案1】:

如果在同一行上找到搜索模式,那么您可以得到您看到的结果:

假设你在寻找:

abc
def
ghi
jkl

数据文件是:

abcdefghijklmnoprstuvwxzy

那么一次性命令将打印 1,循环将打印 4。

【讨论】:

  • 问题的可能原因(+1 票),但事实并非如此。请参阅我对模式发生位置的更新。
  • 那么是时候让 wc 退出系统并查看原始形式的 egrep 的结果了。您可能还想使用“-n”选项来报告行号。因为你只得到十几行输出,所以它不会太糟糕。您也许可以使用“cut -c1-70”,这样长线会更短。
  • 您要匹配的数据中是否有正则表达式元字符?这也可能使事情变得混乱。但是,您现在可能需要手动分析两组不同的结果。 FWIW:最后想到的是“egrep 中的错误”;这是最不可能的。
【解决方案2】:

在第二个版本中,读取的行是否包含 shell 正在为您扩展/替换的内容?然后 grep 在读取模式本身时不会完成此操作,从而导致匹配不同的模式发送。

我不完全确定 shell 是否在这样的调用中对变量值进行任何扩展,但至少这是一个想法。

编辑:不,它似乎没有做任何替换。但这可能是引用问题,如果您的模式包含空格,则 for 循环将逐步遍历每个标记,而不是遍历每一行。看看@987654321@ bash 内置函数。

【讨论】:

  • 这可能是一个可能的原因 (+1),但在这种情况下并非如此,请参阅我的模式更新。
【解决方案3】:

您在 ~/tmp/tmpgrep2 中有任何重复项吗? Egrep 只会使用一次欺骗,但您的循环将使用每次出现。

通过执行以下操作摆脱欺骗:

$ for lines in `sort < ~/tmp/tmpgrep2 | uniq` ; do  egrep $lines orig_20_L_A_20090228.txt ; done | wc -l

【讨论】:

  • +1 因为这可能是原因,但在我的情况下不是。我的模式文件中没有重复项。
【解决方案4】:

我第二个@unwind。

您为什么不运行没有wc -l 并查看每次搜索的结果?

也许:

for lines in `cat ~/tmp/tmpgrep2` ; do echo $lines ; done

现在看看 shell 正在处理$lines

【讨论】:

  • 我这样做了。刚刚添加了 wc -l 以表明它的行为很奇怪。
【解决方案5】:

其他人已经提出了我会看的大部分内容。我要检查的下一件事是环境变量 GREP_OPTIONS,或者在您的机器上调用的任何内容。在使用干扰环境设置的命令行参数时,我收到了最奇怪的错误消息或行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多