2 番目のファイルの範囲に属する列に基づいてファイルの行のサブセットを印刷します。

2 番目のファイルの範囲に属する列に基づいてファイルの行のサブセットを印刷します。

4つの列()を持つファイルがありますfile1.txt

chr1    1156    G       G
chr1    1157    A       A
chr1    1165    T       T
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T
chr1    1181    C       C
chr1    1186    G       G

2番目のファイル(file2.txt)には範囲、2つの列が含まれています。

1100    1160
1170    1180

file12列が範囲に属する行を抽出したいと思いますfile2。上記の例では、目的の出力は次のようになります。

chr1    1156    G       G
chr1    1157    A       A
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T

同様の投稿に基づいて試しましたが、結果は出ませんでした。

awk 'NR==FNR{ range[$1,$2]; next }{for(x in range) {split(x, check, SUBSEP); if($2>=check[1] && $2<=check[2]) print}} ' file2.txt file1.txt > output.txt

私も同じ幸運で以下を試しました。

awk 'NR == FNR {ref[$1][$2]} if ($1 <= key && key <= $2) sum += ref[$2][key] print $0, sum} file2.txt file1.txt > output.txt

誰でも提案があれば大変感謝します。

答え1

次のawkプログラムは、次のことを行う必要があります。

awk 'NR==FNR{rng++;start[rng]=$1;end[rng]=$2;next}
     {for (i=1;i<=rng;i++) if (($2>=start[i])&&($2<=end[i])) {print; next}}' file2.txt file1.txt

仕組みは次のとおりです。

  • 最初の入力ファイル(ファイルごとのfile2.txtラインカウンタと同じグローバルラインカウンタとして表示されます)の解析中に、範囲の開始番号と終了番号を2つの配列に登録し(1つの配列の範囲数を計算している間)、カウンタ)。その後すぐに次の実行ラインにジャンプします。NRFNRstartendrng
  • file1.txtNRこれより大きい)を処理するときは、各行の列2がそれぞれおよび配列の対応する項目によって指定された範囲内にあることをFNR確認してください。その場合は、現在の行を印刷し、次の行にジャンプします。startend

答え2

どちらのファイルも何千行もの長さです。

したがって、過去30年間のコンピュータでは、何千もの行がまったく多くのデータではありません。効率はあなたにとって重要ではありません。 (おおよその計算:最初のファイルは1行に32バイト、2番目のファイルは1行に16バイトなので、1行に合計48バイトです。すると、4,400万個を読むことができます。心配せずにRAMに行を追加してください。

これは遺伝体学/生物情報学のように見えるので、とにかくPythonにさらされる可能性が高いと思います。

#!/usr/bin/env python3
file1 = open("file1.txt", "r", encoding="ascii")
file2 = open("file2.txt", "r", encoding="ascii")

lines1 = file1.readlines()
lines2 = file2.readlines()

file1.close()
file2.close()

for dataline, rangeline in zip(lines1, lines2):
  splitrange = rangeline.split()
  lower = int(splitrange[0])
  upper = int(splitrange[1])
  
  ignore, valuestring, nucleotide1, nucleotide2 = dataline.split()
  value = int(valuestring)
  if lower <= value and value <= upper:
    print(dataline)

それはすべてです。

ジェジュンほど簡潔かawk?当然じゃない。これはできるだけ早いですか?いいえ、まったくそうではありません(しかしそれは問題ではありません)。その週に何が起こったのか覚えていますか?おそらく。

述べたように、AWKの設計目的とはまったく関係のない他のタスクを実行する可能性が高いため、Pythonはおそらく自然なツールです。学ぶことはほぼ確実です。クリーチャーPython良いアイデアです。

答え3

2つの呼び出しを使用してくださいawk

<file2.txt awk '{ print "$2 >= " $1 " && $2 <= " $2 }' |
           awk -f - file1.txt

答え4

cat file2 |while read line ; do col1=$(echo $line| awk '{print $1}'); col2=$(echo $line | awk '{print $2}'); cat file1|while read fine; do echo $fine |awk -v col1="$col1" -v col2="$col2" '$2 >=col1 && $2 <col2'; done; done

出力

chr1    1156    G       G
chr1    1157    A       A
chr1    1173    C       C
chr1    1175    G       G
chr1    1178    T       T

関連情報