2つのCSVファイルがあります。
- 1つは長い列です:
Chr_Name
、、、、、、。h
j
start_pos
end_pos
- もう一つは熱と
Chr_Name
。position
Chr_Name
最初のファイルに基づいて最初のファイルの行をフィルタリングし、最初のファイルの先頭と最後の間の位置に基づいて行をフィルタリングする必要があります。
どうすればいいですか?
例:
- ファイル1:
Chrk, 10, 20, 1010, 1025 Chrk, 20, 10, 1020, 1040 ChrM, 10, 10, 50, 120
- ファイル2:
Chrk, 1030 ChrM, 70
- 必須出力ファイル:
Chrk, 20, 10, 1020, 1040 ChrM, 10, 10, 50, 120
答え1
次の2つのCSVファイルがあるとします。
$ cat file1
Chr_Name,h,j,start_pos,end_pos
Chrk,10,20,1010,1025
Chrk,20,10,1020,1040
ChrM,10,10,50,120
$ cat file2
Chr_Name,position
Chrk,1030
ChrM,70
あなたはそれを使用することができますミラー(mlr
)到着参加する共通フィールドに2つのファイルChr_Name
、フィルターposition
とfinallyの間のフィールドを持つレコードのみを抽出してstart_pos
結果データを取得します。end_pos
切るposition
データに不要なフィールドがあります。
$ mlr --csv join -f file2 -j Chr_Name then filter '$start_pos <= $position && $position <= $end_pos' then cut -x -f position file1
Chr_Name,h,j,start_pos,end_pos
Chrk,20,10,1020,1040
ChrM,10,10,50,120
コマンドmlr
の形式は次のとおりです。
mlr --csv \
join -f file2 -j Chr_Name then \
filter '$start_pos <= $position && $position <= $end_pos' then \
cut -x -f position \
file1
上記と同じ2つのファイルを使用しますが、SQLite3とメモリ内データベースを使用します。Marcus Müllerがコメントで提案したように:
$ sqlite3 :memory: '.mode csv' '.headers on' '.import file1 file1' '.import file2 file2' 'SELECT file1.* FROM file1 JOIN file2 ON (file1.Chr_Name = file2.Chr_name) WHERE CAST(position AS INTEGER) BETWEEN start_pos AND end_pos'
Chr_Name,h,j,start_pos,end_pos
Chrk,20,10,1020,1040
ChrM,10,10,50,120
SQLite3ステートメント:
.mode csv
.headers on
.import file1 file1
.import file2 file2
SELECT file1.* FROM file1
JOIN file2 ON (file1.Chr_Name = file2.Chr_name)
WHERE CAST(position AS INTEGER) BETWEEN start_pos AND end_pos
ダッシュコマンドは両方のファイルをテーブルにインポートし、file1
ステートメントfile2
はSELECT
実際のクエリを実行します。
答え2
■実際にスペースがあるかどうかにかかわらず、awkを使用してください,
。
$ awk -F', *' 'NR==FNR{a[$1]=$2; next} ($1 in a) && ($4 <= a[$1]) && (a[$1] <= $5)' File2 File1
Chrk, 20, 10, 1020, 1040
ChrM, 10, 10, 50, 120