動機

之前為了從log中找出遺失的pid,所以找到了講怎麼用bash做set operation

超實用,紀錄一下

資料結構

Set有許多種實做方法,像hash或是array bash沒有hash只有array,所以接下去就是看如何用array實現

這裡就是去重複加排序過就是set

需要工具

  1. 排序: sort -n
  2. 去重複: uniq
  3. 比較: grep, comm

comm

會一行一行的比,輸出三個column,

  1. 在第一個file有的行
  2. 在第二個file有的行
  3. 在兩個file都有的行

用tab分開,像

1
  2
    3

awk

Set operation

Union

可以像讓兩個array變成set在合併再轉成一次set

array => set
array => set

set * set => array

array => set
cat <(sort A | uniq) <(sort B | uniq) | sort | uniq

或是,先合併再轉成set

array * array => array

array => set
cat A B | sort | uniq

Intersection

先合併再取重複

array * array => array

array => set
cat A B | sort -n | uniq -d # d for duplicate
# OR
comm -12 <(sort -n A) <(sort -n B) # dont print things only appear in first file or second file

Complement

comm -23 <(sort -n A) <(sort -n B)

Cardinality

就計數

sort -n A | uniq | wc -l

Symmetric Difference

取只在某一個檔案存在的東西

comm -3 <(cat A | sort -n) <(cat B | sort -n) | sed 's/\t//g' | awk 'NF' | sort -n
# awk 'NF' is for deleting empty lines

IsSubset

comm -23 <(sort subset | uniq) <(sort set | uniq) | head -1

Ref

Set Operations in the Unix Shell recursion function with awk