2016-11-23 7 views
3

特定のディレクトリ(シーケンスと呼ばれる)のすべてのファイルを繰り返し処理し、各ファイルに対して2つの機能を実行しようとしています。私は個々のファイル上でそれらを実行できるので、関数(blastpとcat行)が機能することを知っています。通常、私はクエリ、出力などの特定のファイル名を持っていますが、ループが多くのファイルを処理できるように変数を使用しようとしています。ディレクトリ内のファイルを繰り返し、出力ファイルを作成するlinux

(免責事項:私はコーディングが新しくなりました。)自分のファイル名を自分の関数内で使用しようとすると重大な問題に遭遇していると思います。そのままでは、私のコードは実行されますが、余分な意図しないファイルがたくさん作成されます。これは私のスクリプトが行うことを意図したものです:

行1: "シーケンス"ディレクトリのすべてのファイルを繰り返します。 (すべてが ".fa"で終わっていれば役に立ちます)

3行目:ファイル名を変数として認識します。

4行目: "query"フラグの引数としてファイル名を使用してblastp関数を実行します。常に "database.faa"を使用してください。これは、 "db"フラグの引数として指定し、最初のファイルと同じ名前が末尾に ".txt"を持つ新しいファイルに結果を出力します。

行5:行4からの出力ファイルの一部を、最初のファイルと同じ名前が末尾に「_top_hits.txt」という名前の新しいファイルに出力します。

for sequence in ./sequences/{.,}*; 
    do 
      echo "$sequence"; 
      blastp -query $sequence -db database.faa -out ${sequence}.txt -evalue 1e-10 -outfmt 7 
      cat ${sequence}.txt | awk '/hits found/{getline;print}' | grep -v "#">${sequence}_top_hits.txt 
    done 

私はこのコードを実行したとき、それは私に、ディレクトリ内の各ファイルから派生し6つの新しいファイルを与えた(そして、彼らは、同じディレクトリ内のすべてのだった - 。私は自分のフォルダにそれらすべてを持っていることを好むだろうがどのようにそれをしてもいいですか?)。彼らはすべて空だった。接尾辞は ".txt"、 ".txt.txt"、 ".txt_top_hits.txt"、 "_top_hits.txt"、 "_top_hits.txt.txt"、および "_top_hits.txt_top_hits.txt"でした。

私が何かを明確にするための詳細情報を提供できる場合は、私に知らせてください。

+2

少なくとも1つの問題は、同じ機能を同じディレクトリで複数回実行しようとしているようです。あなたがそれを実行するたびに、前の実行で生成した新しいファイルをループが見つけ、それを操作しようとしていると思います。私が知る限り、あなたは '* .fa'で終わるファイルにあなたのファイル検索を制限していませんが、あなたがそれをすることをお勧めします。さもなければ、あなたは新しく出力された '.txt'ファイルを処理し続け、より誤った出力を生成します。 – aardvarkk

+0

私は同意する、私はそれを行う必要があります。私はそれを解決するための別の方法は、すべての出力ファイルを別々のディレクトリに出力することだと思います。 * .faで終わるファイルを繰り返し処理するにはどうすればよいですか?それを1行目に入れますか? – lynkyra

答えて

3

あなたは*.faファイルにのみ興味があれば私はこのようなものだけ一致するファイルへのご入力を制限する:

for sequence in sequences/*.fa; do

0

私はあなたに以下の改善を提案することができます

for fasta_file in ./sequences/*.fa # ";" is not necessary if you already have a new line for your "do" 
do 
    # ${variable%something} is the part of $variable 
    # before the string "something" 
    # basename path/to/file is the name of the file 
    # without the full path 
    # $(some command) allows you to use the result of the command as a string 
    # Combining the above, we can form a string based on our fasta file 
    # This string can be useful to name stuff in a clean manner later 
    sequence_name=$(basename ${fasta_file%.fa}) 
    echo ${sequence_name} 
    # Create a directory for the results for this sequence 
    # -p option avoids a failure in case the directory already exists 
    mkdir -p ${sequence_name} 
    # Define the name of the file for the results 
    # (including our previously created directory in its path) 
    blast_results=${sequence_name}/${sequence_name}_blast.txt 
    blastp -query ${fasta_file} -db database.faa \ 
     -out ${blast_results} \ 
     -evalue 1e-10 -outfmt 7 
    # Define a file name for the top hits 
    top_hits=${sequence_name}/${sequence_name}_top_hits.txt 
    # alternatively, using "%" 
    #top_hits=${blast_results%_blast.txt}_top_hits.txt 
    # No need to cat: awk can take a file as argument 
    awk '/hits found/{getline;print}' ${blast_results} \ 
     | grep -v "#" > ${sequence_name}_top_hits.txt 
done 

を意味のある名前をつけて中間変数を作りました。 私は\を使って行末をエスケープし、いくつかの行にコマンドを入力できるようにしました。 コードの可読性が向上することを願っています。

私はテストしていません。タイプミスがあるかもしれません。

関連する問題