kuroの覚え書き

96の個人的覚え書き

in_()に入るlistのサイズは最大で999らしい

あるqueryを組み立てて、結果出てくるものからlistを作って、そのlistに含まれるものをin_()を使って別のqueryの中でfilterしたいと思った。

        q = session.query(Rna_snp)
        snp = q.distinct(Rna_snp.snp_hash).group_by(Rna_snp.snp_hash)snp.all()
        snp_list = []
        for query in snp:
            snp_list.append(query.snp_hash)

        q = session.query(Rna_snp)
        samp = re.split('[, ]', form.names2.data)
        q = q.filter(Rna_snp.sampleName.in_(samp)).filter(Rna_snp.snp_hash.in_(snp_list))

こんな感じ。
これ自体、書式には間違いはなく、ちゃんとfilterがかけられるはずなんだが、snp_listの中身が10000個とかになっていると、エラーが出てしまうのな。

そこで、もうここはSQLでなんとかするのは諦めて、
前半のqueryで出てくるsnp_hashと後半のqueryで出てくるsnp_hashをそれぞれファイルに出力して、重複のあるhashだけを抽出することにした。
最初、excelの関数でなんとかしようとしてみたけど、excelはやっぱり行数が多いと動作が遅く、固まってしまうことが多く、使い物にならなかった。なので、shellスクリプトでちゃっちゃと処理をすることにした。awkあたりを使えばできそうだなと調べていたが、実は簡単なワンライナーでできてしまうことがわかった。

cat a.txt b.txt | sort | uniq -d > c.txt

これだけ。これでa.txtとb.txtを比べて、2つで重複する行だけを抜き出してc.txtにする。
例えば
a.txt

aaa
aab
aac
aad
aae
aba
abb
abc
abd
abe
aca
acb
acc
acd
ace

b.txt

aad
aaf
abc
abe
acd
acf

c.txt

aad
abc
abe
acd

こんな感じになる。
また、重複しない行だけを取り出すなら
cat a.txt b.txt | sort | uniq -u > c.txt

上の例で
cat b.txt c.txt | sort | uniq -u > d.txt
とやると
d.txt

aaf
acf

となる。