2017-01-25 49 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正確,括號表達式可以包含您所描述的字符列表和/或字符類和/或字符範圍,並且它們與該括號表達式所描述的任何單個字符相匹配。 –