2017-05-05 7 views
0

を失敗した私は、名前(* fastq.gz.fasta-BLASTDB)のファイル名を含むファイル(* fastq.gz.fasta)とディレクトリ、持っている:バッシュ(スプリット)ファイル名の比較は私のディレクトリで

IVC6_Meino.clust.gz.fasta-blastdb 
IVC5_Mehiv.clust.gz.fasta-blastdb 
.... 
IVC6_Meino.clust.gz.fasta 
IVC5_Mehiv.clust.gz.fasta 
.... 

bashスクリプトでは、後者のcutオプションを使ってファイル名とディレクトリ名を比較し、ファイル名部分のみを抽出したいと考えています。これらの2つの名前が一致すれば、私はさらなるものをしたい(それぞれエコーマッチまたはマッチなし)。 私は、次のコード書かれている:

#!/bin/bash 

for file in *.fasta 
do 
    for db in *-blastdb 
    do 
     echo $file, $db | cut -d '-' -f 1 
     if [[ $file = "$db | cut -d '-' -f 1" ]]; then 
      echo "match" 
     else 
      echo "no match" 
     fi 
    done 
done 

をしかし、それはマッチを検出しません。出力は次のようになります。
...

IVC6_Meino.clust.gz.fasta, IIIA11_Meova.clust.gz.fasta 
no match 
IVC6_Meino.clust.gz.fasta, IVC5_Mehiv.clust.gz.fasta 
no match 
IVC6_Meino.clust.gz.fasta, IVC6_Meino.clust.gz.fasta 
no match 

あなたが見ることができるように最後の行は、文字列が同じように見え、試合をお読みください。 私は何が欠けていますか?

答えて

0

あなたはこれをより簡単に行うためにparameter expansionを使用することができます。

for file in *.fasta 
do 
    for db in *-blastdb 
    do 
     echo "$file", "$db"   
     if [[ "${file%%.fasta}" = "${db%%.fasta-blastdb}" ]]; then 
      echo "match" 
     else 
      echo "no match" 
     fi 
    done 
done 

あなたはあなたを修正したい場合は、問題がechoそれ$db | cut -d '-' -f 1の使用であるパイプを印刷しているechoことが表示されます。そうではありません。 cutが印刷されています。あなたが[[ $file = "$db | cut -d '-' -f 1" ]]を行うと、それは[[ $file = [return code from last pipe component] ]]

と等価であるあなたは、パイプの出力をキャプチャして、あなたが$dbの内容は、パイプを開始するために取得するechoに必要に$(..)シェル構造体を使用する必要があります。 "$db"を引用すると、単語の分割や変数の内容からのグロブが発生しません。

ので、同様に:あなたは、バッシュで引用し、自由にShellCheckを使用するには注意が

for file in *.fasta 
do 
    for db in *-blastdb 
    do 
     ts=$(echo "$db" | cut -d '-' -f 1) 
     echo "$file", "$ts" 
     if [[ "$file" = "$ts" ]]; then 
      echo "match" 
     else 
      echo "no match" 
     fi 
    done 
done    # this works I think -- not tested... 

してください。


あなたが持っている構造も、最も効率的ではありません。 *-blastdbにあるファイルごとに*-blastdbグロブを1回ループします。たくさんのファイルがあると、それは本当に遅くなる可能性があります。それを解決するために

、あなたは(あなたがバッシュ4+を持っている場合、最良)バッシュアレイと、このループを書き直したりawkを使用することができます。

ext1=.fasta 
ext2=.fasta-blastdb 
awk 'FNR==NR{ 
       s=$0 
       sub("\\"ext1"$","",s) 
       seen[s]=$0 
       next} 
       { 
       s=$0 
       sub("\\"ext2"$","",s) 
       if (s in seen) 
       print seen[s], $0 
       } 
       ' ext1="$ext1" ext2="$ext2" <(for fn in *$ext1; do echo "$fn"; done) <(for fn in *$ext2; do echo "$fn"; done) 

各グロブは一度だけ実行されているとawkをテストするために、配列を使用していますベースネームが同じ場合。

最高

関連する問題