2017-01-25 48 views
3

我有两个C源文件有很多定义,我想将它们相互比较并过滤出不匹配的行。 grep的(grep NO_BCM_ include/soc/mcm/allenum.h | grep -v 56440)的第一个文件的输出可能是这样:比较两个greps的输出

... 
... 
# 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中缺失。我如何最好地解决这个问题? 谢谢

+0

'差异文件1 file2' –

+0

[编辑]你的问题,包括给定输入的预期输出。 –

回答

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不在创建的哈希中的行。

+1

@EdMorton:谢谢埃德!更新! – Inian

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

名称 COMM - 比较一行

概要 COMM [选项]两个排序文件一行... 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,第3列包含两个文件共有的行。

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

:对于独立于grep的+1,FS ='[()]'用于指定[]中的任何单个字符可以是空格分隔符,对吧? – Vicky

+0

我的意思是,如果一个文件有:(冒号),(逗号),| (管道)字符,我希望他们都被视为字段分隔符然后我可以指定FS为FS = [:,|]? – Vicky

+1

@ user3369871正确,括号表达式可以包含您所描述的字符列表和/或字符类和/或字符范围,并且它们与该括号表达式所描述的任何单个字符相匹配。 –