比较两个greps的输出

时间:2017-01-25 19:45:05

标签: bash awk grep comm

我有两个带有大量定义的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中缺少的任何类型编号。我最好怎么做? 谢谢

3 个答案:

答案 0 :(得分:4)

以这种方式使用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 - 逐行比较两个已排序的文件

     

概要          comm [OPTION] ... FILE1 FILE2

     

说明          逐行比较已排序的文件FILE1和FILE2。

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

FILE2,第三列包含两个文件共有的行。

   -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)

答案 1 :(得分:4)

您可以使用awk逻辑和grep

的两个流程替换处理程序
awk 'FNR==NR{seen[$2]; next}!($2 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是为了确保使用正确的分隔符来解析公共实体。

FS="[()]"是将$2捕获为第二组中的唯一字段,将FS=" "捕获为第一组的默认空白限制。

awk的核心逻辑是识别不重复的元素,即FNR==NR将存储$2中的唯一条目的第一个组解析为哈希映射。解析完所有行后,在第二组上执行!($2 in seen),这意味着过滤那些在创建的哈希中不存在第二组$2的行。

答案 2 :(得分:3)

如果没有样本输入文件的周围环境并且没有预期的输出,很难说,但听起来这就是你所需要的:

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