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