私は次のような状況にあります。
ファイル1は次のようになります。
A
B
C
ファイル2は次のようになります。
chr1 \t 1234523 \t A
chr3 \t 1234231 \t A
chr6 \t 121233 \t A
chr1 \t 1126685 \t B
chr1 \t 15834523 \t B
chr4 \t 12345647 \t C
chr12 \t 1456523 \t C
出力を得たいです。
A \t 3
B \t 2
C \t 2
私はこれができることを知っています
grep A File2 | wc -l
ただし、File1のすべての行(700)に対してこれを行う必要があります。
これをどのように自動化できますか?
答え1
\t
sは実際にはタブ文字であり、同じ列にあり、AはAAではなくAにのみ一致すると仮定します。a
A、B、C を含むファイルと一致b
するかどうかを計算するファイル (提供された 2 番目のファイル) を想定します。
まず、可能な一致のみを取得し、
b
残りはすべて無視する必要があります。これは、ファイルの一部を切り取るためにb
使用できる3番目の列です。cut
カット -f 3b
その後、それを発生回数と発生回数のリストに変換する必要があります。
uniq
出力をソートして計算するために使用できます。cut
ソート|ユニクロ-c
最後に、あなたはこれのためにみんなin
b
ですが、の値のみが必要ですa
。join
これを使用して、共通フィールド(この場合、最初と唯一のフィールド(デフォルトではa
これを行うように見えます)と2番目のファイル(2
)でb
ある2番目のフィールド(-2
))から2つの異なるファイルをリンクできます。接続-2 2a 結果-b
いくつかの異なる方法で接続することができ、1つの可能な方法は、bash
プロセス交換で名前付きパイプを使用することです。
join -2 2 a <(cut -f 3 b | sort | uniq -c)
これは、bを3回だけ処理し(他の列と削除sort
)、uniq
結合が入力をソートする必要があるため、各ファイルを一度だけ読み取るため、grep単独よりも少なくとも優れています。もちろん、これは私が作成した仮定に依存します(そしてソートも必要ですa
が、これは以前のソートされていない場合を<(sort a)
置き換えるだけです)。a
答え2
入力例では、タブ区切りレコードの最後のフィールドにあるすべての一意の値を計算しようとしています。これを行うawkスニペットは次のとおりです。
awk -F '\t' '
{++a[$NF]}
END {for (x in a) {print x "\t" a[x]}}
' File2
答え3
whileループを使用してこれを行うことができます。
while read arg < FILE1; do echo -n -e "$arg\t"; grep "$arg" FILE2 | wc -l; done
これはFILE1を読み取り、各行に対してforループは文字列を$ arg変数に格納します。
次に $arg を echo します (-n は末尾に行戻り (\n) を挿入しないことを意味し、 -e はエスケープ文字を実行することを意味します)。
次に、FILE2で見つかった$ argの発生回数を表示します。