Bashで文字列の差集合を求める関数を実装しました。
結構つまりながら実装したのでブログに書いておきます。
考え方
- 集合Aと集合Bの積集合(共通要素の集合)を求める。
- 集合Aと「1. 集合Aと集合Bの積集合」で重複していない要素を求める。
実装
except() { # 文字列を集合と見たときの差集合`a - b`を返す local a b intersection difference a=$1 b=$2 intersection=($(for item in ${a} ${b}; do echo "$item"; done | sort | uniq -d)) difference=($(for item in ${a} ${intersection[@]}; do echo "$item"; done | sort | uniq -u)) echo "${difference[@]}" }
出力はこうなる。
except "a b c d" "c d e" #==> a b except "( "b" "c" "d" "a" )" "( "c" "e" )" #==> a b d array1=( "a" "b" "c" "d" "e" ) array2=( "a" "d" ) _except "${array1[*]}" "${array2[*]}" #==> b c e
詰まったところ
- Bash慣れてなくて、文字列なのか、配列なのかを混同していた。
[@]
と[*]
が各要素をつなげるのか、別の要素にするのか(ちょっとまだよく分かっていない)
もっと簡単にできるよということがあれば、コメントお願いします。