X

使用 grep 過濾兩個檔案(不)重複的內容

Linux 常常使用 grep 來找某段字串(可以使用 regex),不過 grep 還有許多強大的功能,例如:

兩個檔案內容,想要把兩個檔案都有的內容撈出來,或者把其中 A檔案 當過濾(Filter)條件,另外 B檔案有出現 A檔案 的內容,全部過濾掉,都可以靠 grep 達成。

使用 grep 過濾兩個檔案(不)重複的內容

使用 grep 抓出兩個檔案都有的內容

  1. 整行「部份」比對正確就印出來
  2. 整行「完全」比對正確才印出來

註:避免有編碼的意外,建議執行方式 LC_ALL=C grep -Fwf ...

檔案內容

  • filter
    test
    test3
  • data.txt
    test
    test
    test3 12
    test3
    test2
    test2

使用 grep 比對兩個檔案 整行「部份」比對正確印出

  • grep -Fwf filter data.txt # w = word,抓出 partial match 的
    test
    test
    test3 12
    test3

使用 grep 比對兩個檔案 整行「完全」比對正確印出

  • grep -Fxf filter data.txt # x = line,抓出 full match 的
    test
    test
    test3

使用 grep 將 A檔案(完整內容) 過濾掉 B檔案(Filter) 的內容

A檔案 跟 B檔案 重複的資料,要過濾掉,從 A檔案 過濾掉 B檔案內有的內容

  • 註:A檔案是完整內容,B檔案內容 是 A檔案需要過濾掉的內容條件

檔案內容

  • $ cat a
    1
    2
    3
    4
    5
    test3 12
    [7
  • $ cat b
    3
    4
    6
    test3
    [8

使用 grep 過濾兩個檔案 整行「部份」過濾正確印出

  • grep -f b -Fv a # 3, 4, test3 12 會被過濾掉(partial match)
    1
    2
    5
    [7

使用 grep 過濾兩個檔案 整行「完全」過濾正確印出

  • 下述語法都是一樣的 (a full data,b filter data)
  • grep -f b -Fxv a
  • grep -Fxvf b a # f 需要放在最後面
  • LC_ALL=C grep -Fxvf b a # f 需要放在最後面,3, 4 被過濾掉
    1
    2
    5
    test3 12
    [7

上述 grep 過濾兩個檔案內容,可以用下述程式再做一次驗證

<?php
// a檔案為完整內容,b檔案內容若在 a檔案有出現,則移除掉
$data   = file('a');
$filter = file('b');

foreach ($filter as $line)
    if (isset($data[$line]))
        unset($data[$line]);

echo implode($data);
?>

grep 使用 regex 把內容找出來

Blog 首頁想將 a href 的內容都撈出來,可以使用下述:

  • grep -P 'href="(https://.?)" rel=' index.html -o
  • 註:可以寫更簡單簡化點,這個範例刻意多把 rel= 也加入條件印出來
Tsung: 對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.
Related Post