比较两个 greps 的输出

Comparing output from two greps

我有两个包含大量定义的 C 源文件,我想将它们相互比较并过滤掉不匹配的行。 第一个文件的 grep (grep NO_BCM_ include/soc/mcm/allenum.h | grep -v 56440) 输出可能如下所示:

...
...
# if !defined(NO_BCM_5675_A0)
# if !defined(NO_BCM_88660_A0)
# if !defined(NO_BCM_2801PM_A0)
...
...

第二个的 grep (grep "define NO_BCM" include/sdk_custom_config.h) 看起来像:

...
...
#define NO_BCM_56260_B0
#define NO_BCM_5675_A0
#define NO_BCM_56160_A0
...
...

所以现在我想在上面的大括号中找到下面 #define 中缺少的任何类型编号。我该如何最好地解决这个问题? 谢谢

这样使用comm

comm -23 <(grep NO_BCM_ include/soc/mcm/allenum.h | cut -f2 -d'(' | cut -f1 -d')' | sort) <(grep "define NO_BCM" include/sdk_custom_config.h | cut -f2 -d' ' | sort)

这将为 include/soc/mcm/allenum.h 提供独特的令牌。

输出:

NO_BCM_2801PM_A0
NO_BCM_88660_A0

如果你想要那个文件的完整行,那么你可以使用 fgrep:

fgrep -f <(comm -23 <(grep NO_BCM_ include/soc/mcm/allenum.h | cut -f2 -d'(' | cut -f1 -d')' | sort) <(grep "define NO_BCM" include/sdk_custom_config.h | cut -f2 -d' ' | sort)) include/soc/mcm/allenum.h

输出:

# if !defined(NO_BCM_88660_A0)
# if !defined(NO_BCM_2801PM_A0)

关于comm

NAME comm - compare two sorted files line by line

SYNOPSIS comm [OPTION]... FILE1 FILE2

DESCRIPTION Compare sorted files FILE1 and FILE2 line by line.

   With no options, produce three-column output.  Column one contains lines unique to FILE1, column two contains lines unique to

FILE2, and column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)
   -2     suppress column 2 (lines unique to FILE2)
   -3     suppress column 3 (lines that appear in both files)

您可以将 awk 逻辑与两个 process-substitution 处理程序一起用于 grep

awk 'FNR==NR{seen[]; next}!( in seen)' FS=" " <(grep "define NO_BCM" include/sdk_custom_config.h) FS="[()]" <(grep NO_BCM_ include/soc/mcm/allenum.h | grep -v 56440)
# if !defined(NO_BCM_88660_A0)
# if !defined(NO_BCM_2801PM_A0)

想法是 <() 中的命令将根据需要执行并生成输出。在输出之前使用 FS 是为了确保用 proper-delimiter.

解析公共实体

FS="[()]" 是捕获 </code> 作为 second-group 中的唯一字段和 <code>FS=" " 作为第一组的默认空格 de-limiting。

awk的核心逻辑是识别不重复的元素,即FNR==NR解析第一组存储在</code>中的唯一条目作为hash-map。解析完所有行后,将在 second-group 上执行 <code>!( in seen),这意味着过滤那些 second-group 中的 不存在于创建的散列中的行。

很难说没有示例输入文件的周围上下文并且没有预期的输出,但听起来这就是您所需要的:

awk '!/define.*NO_BCM_/{next} NR==FNR{defined[];next} !( in defined)' include/sdk_custom_config.h FS='[()]' include/soc/mcm/allenum.h