【问题标题】:Pipe search pattern to BSD grep管道搜索模式到 BSD grep
【发布时间】:2016-06-03 08:04:11
【问题描述】:

我有这个在 OS X 10.6.8 (Snow Leopard) 中运行良好的命令字符串(它告诉我它的 grep 是 grep (GNU grep) 2.5.1)...

$ grep -hi 'TERM' file1.txt | cut -d '|' -f 3 | grep -f - file2.txt 

(在 file1 中查找所有包含 TERM 的行,将每一行缩减为字段 3 中的唯一 ID 号,然后在 file2 中查找这些 ID)

然而这在 OS X 10.11.5 (El Capitan) 中失败了(它告诉我它的 grep 是 grep (BSD grep) 2.5.1-FreeBSD)...

grep: -: No such file or directory

我真的不想在这台机器上安装 GNU grep。有没有办法修复第二个 grep 命令,以便 BSD grep 可以工作?或者一般来说有更好的方法?

一些示例代码:

file1.txt 看起来像:

Jones Inc||000123||foo||bar 
TerminatorLLC||000124||foo||bar
Conan LP||000125||foo||bar
Termites-R-Us||000126||foo||bar

file2.txt 类似:

000123||210 Main Street||moo||car
000124||Los Angeles||moo||car
000125||Mythical Kingdom||moo||car
000126||Your Woodwork||moo||car

【问题讨论】:

    标签: bash shell unix grep bsd


    【解决方案1】:

    - 通常指 stdin 或 stdout,-f 将在 B 中搜索 A 中的行:

    grep -f A B
    

    <(...)(称为process substitution)将创建一个带有...输出的“文件”:

    % echo <(ls)
    /dev/fd/63    
    

    有了这些知识,您可以将命令更改为:

    grep -f <(grep -hi 'TERM' file1.txt | cut -d '|' -f 3) file2.txt
    

    在 AWK 中:

    awk -F'|' 'NR == FNR { if ( /[tT][eE][rR][mM]/ ) a[$3] = 1; next }a[$1]' file1.txt file2.txt
    

    @fedorqui 建议的替代方案,但修改为不使用gawk's IGNORECASE。注意读取文件file2.txtfile1.txt

    awk -F'|' 'NR == FNR { a[$1] = $0; next } /[tT][eE][rR][mM]/ { print a[$3] }' file2.txt file1.txt
    

    【讨论】:

    • 感谢您提供此 grep 模式。它适用于 GNU 或 BSD grep。这两个文件大约有 750k 行。 GNU grep 在 33 秒内完成; BSD grep 已经运行了 4 分钟,但仍然没有显示第一个结果。如果不出意外,您提供的如此友好的代码让我相信 BSD grep 是垃圾。
    • @andlrc 的 awk 似乎可以工作,但@fedorqui 的 awk 似乎没有。
    • @fedorqui 感谢您花在这方面的时间。但即使在重新检查文件 2 在文件 1 之前......它似乎也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2010-10-12
    • 2018-07-30
    • 2010-10-01
    相关资源
    最近更新 更多