• 検索結果がありません。

unix15-script2_09.key

N/A
N/A
Protected

Academic year: 2021

シェア "unix15-script2_09.key"

Copied!
21
0
0

読み込み中.... (全文を見る)

全文

(1)

UNIX講習会

シェルスクリプト

2

31/July/2015

(2)

シェルスクリプト応用編:

複数ファイルをまとめて処理する

条件違いの同じフォーマットのデータが大量にあるとき

一件づつコマンドを実行するのは大変

ヒューマンエラーの元にもなる

SGEのアレイジョブ機能も使えるが、ごく簡単なコマンド には少々面倒

複数ファイルに対し繰り返し処理をしてくれるシェルスク リプトの書き方

(3)

作業ディレクトリ

~/unix15/sge

$

cd ~/unix15/sge

$

ls script*

script2.sh script3.sh script4.sh

~/unix15/sge/results

 には、

sam ファイルが12個入っていることを確認

$

ls results/*.sam

入っていない場合は以下のようにコピーしてください

$

rm -r results

$

cp -r /usr/local/data/unix15/sge/results .

(4)

for 文

エディタで新しく下記のスクリプトを記述し、script1.sh として保存

実行権を与えてから実行してみる #!/bin/sh for sm in results/*.sam do  echo ${sm} done script1.sh $ chmod +x script1.sh $ ./script1.sh results/ecoli.1.sam results/ecoli.10.sam results/ecoli.11.sam results/ecoli.12.sam $ emacs script1.sh

(5)

繰り返し処理:

for文

文字列やファイルのリストに対し、順番にある決まった処理をする

リストはスペース区切りの文字列挙、配列、数字など

for 後の変数に集合が順番に1つづつ代入され、その後に決まった処 理が行われる

全ての集合が代入され終わったらfor文も終了 for 変数名 in 文字列などの集合 do   処理 done for 開始 繰り返しリスト do 処理 リスト最後? for 終了 done Yes No

(6)

for文に使うリストの例

for i in 1 2 3 4 5 6 7 do… done for i in {1..10} do… done for f in ./* do… done カレントディレクトリ内にある全てのファ イル名をワイルドカード「*」を使って リスト(変数 ${f} にファイル名が1つづつ 代入される) 1∼7までの整数をリスト(変数 ${i} に1∼ 7が順に代入される) 1∼10までの整数をリスト(変数 ${i} に 1∼10が順に代入される)

(7)

if 文

script2.sh に実行権を与えてから実行してみる

bowtieの結果ができているかの簡単なチェック $ chmod +x script2.sh $ ./script2.sh ok $ less script2.sh #!/bin/sh if [ -f results/ecoli.10.sam ] then echo 'ok' else

echo 'not ok' fi

(8)

[ ]

内の条件が真か偽か?で処理を変える

if -> 条件 -> then

if」は必ず「fi」で終わらねばならない

条件を複数設定したい場合は「elif」を使う if [ 条件 ] then   条件が真だった場合の処理 else   偽だった場合の処理 fi

条件分岐:

if 文

if 開始 then 処理 if 終了 fi True False if 条件 else 処理

(9)

複数の条件を設定:elif

条件分岐:

if 文

if [ 条件1 ] then   処理 elif [ 条件2 ] then 処理 elif [ 条件3 ] then 処理 else   全て偽な場合の処理 fi if 開始 then 処理1 if 終了 fi True False if 条件1 else 処理 elif 条件2 then 処理2 True False

(10)

if : 条件判断の演算子

条件判断の [ ] は、test コマンドの代替表現

下記の演算子一覧は man test で見ることができる 数値比較 数1 -eq 数2 両辺が等しいと真 数1 -ne 数2 両辺が等しくないと真 数1 -gt 数21 > 数2 の場合に真1 -lt 数21 < 数2 の場合に真1 -ge 数21 >= 数2 の場合に真1 -le 数21 =< 数2 の場合に真 文字列比較 -n 文字列 文字列の長さが0でなければ真 ! 文字列 文字列の長さが0なら真 文字列1 = 文字列2 両文字列が同じなら真 文字列1 != 文字列2 両文字列が同じでなければ真 ファイルチェック -d ファイル名 ディレクトリなら真 -f ファイル名 通常ファイルなら真 -e ファイル名 ファイルが存在すれば真 -L ファイル名 シンボリックリンクなら真 -r ファイル名 読み取り可能ファイルなら真 -w ファイル名 書き込み可能ファイルなら真 -x ファイル名 実行可能ファイルなら真 -s ファイル名 サイズが0より大きければ真 ファイル名1 -nt ファイル名2 1が2より新しければ真 ファイル名1 -ot ファイル名2 1が2より古ければ真 論理結合 ! 条件 条件が偽であれば真 条件1 -a 条件2 条件1, 2 共真であれば真 条件1 -o 条件2 1, 2 どちらかが真であれば真

(11)

複数のファイル処理

~/sge/results/ 内にある12個の .samファイルを .bamファイル

に変換したい

✓ samtools の sam -> bam 変換

samtools view -bS example.sam > example.bam

(12)

ファイル名を取得するコマンド

:

basename

パスからファイル名だけを取り出して表示

パスとファイル名の末尾から一致する文字列を削除して表示 $ basename ~/unix15/sge/results/ecoli.9.sam ecoli.9.sam

$ basename ~/unix15/sge/results/ecoli.9.sam .sam ecoli.9

$ basename ~/unix15/sge/results/ecoli.10.sam 0.sam ecoli.1

(13)

date コマンド:現在の日時を表示する

basenameコマンドと組み合わせてファイル名を変数に記憶する $ date

2015年 1月 20日 火曜日 11:26:31 JST

$ echo "Today is date"

Today is date

$ echo "Today is `date`"

Today is 2015年 1月 20日 火曜日 11:28:08 JST

挟んだコマンドを実行する

バッククォート

` `

$ fn=`basename result/ecoli.9.sam .sam`

$ echo ${fn}

(14)

sam -> bam 変換

results/ecoli.1.sam を bam に変換し、result/ecoli.1.bam として保存

1) 変数 fn に 「ecoli.1」を記憶しておき、

2) ${fn}.bam という名前でbamファイルを保存

basenameとバッククオートを使って拡張子を

変えた同名ファイルを作る

$ fn=`basename results/ecoli.1.sam .sam`

$ echo ${fn}

ecoli.1

$ samtools view -bS results/ecoli.1.sam > results/${fn}.bam

samtools view -bS example.sam > example.bam

1)

(15)

for文, basename , ` ` を使って取得したファイル名

を確認する

ワイルドカード「*」を使って、

results 内にある全ての .sam

ファイルをリスト

${sm} , ${fn} にはどんな文字が入るか?

$ less script3.sh for sm in results/*.sam do fn=`basename ${sm} .sam` echo ${sm} ${fn} done script3.sh $ chmod +x script3.sh $ ./script3.sh

(16)

演習

for文を使って ~/unix15/sge/results/ 内の全 .samファイルを .bamに

変換する

✓ samtools の sam -> bam 変換

samtools view -bS example.sam > example.bam     

✓ script3.sh を改変して作ること

✓ .bam ファイルも results/ 内に保存すること

✓ 結果のファイル名は、ecoli.1.bam ∼ ecoli.12.bam にすること ✓ basename と バッククォートを使いましょう

✓ qsub する前にsamtoolsコマンド全体を echo で出力してみましょう ✓ テストは ./script3.sh で実施し、echo が上手くいったらechoを除いて

(17)

演習

途中経過

script5.sh #!/bin/sh for sm in results/*.sam do fn=`basename ${sm} .sam`

echo “samtools view -bS ${sm} > results/${fn}.bam” done

(18)

演習

解答

script5.sh #!/bin/sh #$ -cwd for sm in results/*.sam do fn=`basename ${sm} .sam`

samtools view -bS ${sm} > results/${fn}.bam done

(19)

名前または数値のリスト:「配列」を作り、記憶しておく

配列名=(リスト…) で作成

$ { 配列名 [ リスト番号 ] } で各リストの値を呼び出す

シェルスクリプトにおける「配列」

$ array=("human" "mouse" "rat")

$ echo ${array}

human

$ echo ${array[2]}

rat

$ echo ${array[@]}  配列全てを表す

human mouse rat

$ fl=(results/*.sam) $ echo ${fl[0]} $ fl=(`ls`) $ echo ${fl[@]} カレントディレクトリのファイル名 リストを配列に results/ 内の.samで終わるファイル名 リストを配列に

human mouse rat

(20)

for文に配列を与え、番号で取り出す

ワイルドカード「*」を使って、results 内にある全ての .sam ファイ ルを配列 ${array} に記憶させる

ファイルは12個あることがわかっているので、1∼12 のリストで内容 を取り出すが、配列の番号は0から始まるので 1 を引いている

for i in {0..11} として 1 を引かなくても良い #!/bin/sh array=(results/*.sam) for i in {1..12} do

fn=`basename ${array[i-1]} .sam` echo $fn ${array[i-1]}

(21)

バッククォート、配列をアレイジョブに応用

ファイル名に連続した数字が付いていなくてもアレイジョブに リストを与えることができる 配列の番号は0から始まるが、SGE_TASK_ID に入るのは1から なので 1を引いている  ${list[${SGE_TASK_ID}-1]} #!/bin/sh #$ -t 1-12 #$ -cwd list=(`ls ../rnaseq/test_fastq/`) bowtie2 -x ../rnaseq/ecoli_genome
 -U ../rnaseq/test_fastq/${list[${SGE_TASK_ID}-1]} -S results/ecoli.${SGE_TASK_ID}.sam script4.sh

参照

関連したドキュメント

However, because the dependent element in (4) is not a gap but a visible pronoun, readers could not realize the existence of relative clause until they encounter the head noun

平成 28 年 7 月 4

あれば、その逸脱に対しては N400 が惹起され、 ELAN や P600 は惹起しないと 考えられる。もし、シカの認可処理に統語的処理と意味的処理の両方が関わっ

(ECシステム提供会社等) 同上 有り PSPが、加盟店のカード情報を 含む決済情報を処理し、アクワ

(5) 帳簿の記載と保存 (法第 12 条の 2 第 14 項、法第 7 条第 15 項、同第 16

前処理フィルタ2B 漏えい個所 漏えいあり 腐⾷あり スラッジ塊あり 異常なし. 

※ 本欄を入力して報告すること により、 「項番 14 」のマスター B/L番号の積荷情報との関

の繰返しになるのでここでは省略する︒ 列記されている