一つの表から情報を抽出したファイルを作り、要素を一つづつ読み込む (2019/4/8追記)


背景と目的

特定の数種類のファイルをサーバーからダウンロード、それを実験区の数だけ繰り返すというルーティンワークが業務の一環として存在する職に就いているのだが、どうやらこの業務に従事していたこれまでの担当者はこれらを全て手作業で行っていたようだ。これをある程度まで自動化するのが目的となります。

作業の概要

ここでは、次世代シークエンサーによる解析後の生ファイル(Fastq)および解析後のファイル(Bam,Bai,Vcf等)の入手を想定しているのだが、ダウンロードするサーバーのディレクトリ構造を見ていると、どうやら単純にサンプル名が必要なだけではなく、サンプル識別用のインデックス配列(バーコードともいう)の情報が必要になるようだ。

1列目にインデックス名、2列目にそのインデックスを用いたサンプル、という形の情報が書かれたテーブルを用意し、個々の情報のみに絞ったファイルを一旦作り分けておいて、そこから個々の情報を読み込むことにする。

概念としては下図のようになる。
なお、サンプルシートはヘッダが存在せず、1行目からサンプル名、インデックス名が始まっているものとする。

ファイルの分割

  • catとawkでファイルを分割する
#!/usr/bin/bash
cat sample_sheet.tsv | awk '{print $1}' > barcode_name.txt
cat sample_sheet.tsv | awk '{print $2}' > sample_name.txt

これで、インデックスまたはサンプルの情報のみを持つテキストファイルが出来上がった。

個々のインデックス名、ファイル名を代入する

  • catとsedで特定の行の情報だけ取得する。

前提条件から、テキストファイルの行数イコールサンプル数となっているため、まずファイルの行数を取得。

row=`cat sample_name.txt | wc -l`
echo $row #行数の確認。

##以下、サンプルの数だけ繰り返し作業をする
for i in `seq $row`
do
    echo $i'番目' #何番目の繰り返しかを表示
cat barcode_name.txt | awk 'NR'==$i #何行目を取得するか指定
a=`sed -n $i'p' barcode_name.txt` #aに、指定した行数のインデックスを代入
echo $a #インデックスを表示

#続いて、同じ作業でサンプル名を取得
cat sample_name.txt | awk 'NR'==$i
b=`sed -n $i'p' sample_name.txt`
echo $b #指定した行のサンプル名を表示

. download.sh #別に用意したダウンロード用のコマンドを格納したシェルスクリプトを走らせる
done
##繰り返し

という感じで、ダウンロード用スクリプトには若干改善の余地があるものの、このファイル分割とファイル読み込みスクリプト自体はちゃんと動いたというささやかな喜び。

追記(2019/4/8)

もう少し簡略化できないかと考えていたら、awkを2回連発したら中間ファイルを作成しないでもイケることに気づきました。

row=`cat sample_name.txt | wc -l`
echo $row
for i in `seq $row`
do
    echo $i'番目'
a=`cat sample_sheet.tsv | awk '{print $1}' | awk 'NR'==$i`
b=`cat sample_sheet.tsv | awk '{print $2}' | awk 'NR'==$i`
echo "バーコード名は"$a
echo "サンプル名は"$b
(中略)
done

おわりに

本稿の作成にあたり、sed, awk, grepの使い分けはじめ諸兄のサイト等を参考にさせていただきました。この場を借りてお礼申し上げます。