whileループで変数が奇妙に動作します。

whileループで変数が奇妙に動作します。

再投稿です生物情報学でも同じ問題が発生します。。提供された回答が私には適していないので、ここに連絡する必要があると思いました。

私のディレクトリは、複数のプロジェクトディレクトリを持つデフォルトディレクトリ( "mgp"で始まる)で構成されています。各プロジェクトディレクトリには複数のメタゲノムディレクトリがあります(「mgm」で始まり、「.3」で終わります)。各メタゲノムディレクトリには常にテキスト.fna(fasta)ファイルがあります。 Fastaファイルは次の構造で定義されます。

>Header1
Sequence1
>Header2
Sequence2

私が望むのは、これらのすべてのfastaファイルを見て、プロジェクトとメタゲノムディレクトリに対応するヘッダーコードに追加するループです。たとえば、プロジェクトディレクトリ mgp83581 の fasta ファイル、メタゲノムサブディレクトリ mgm4729322.3 に次のヘッダーがあるとします。

>seq1
>seq2

...次に変更したいです。

>83581_322_seq1
>83581_322_seq2

基本的に、プロジェクトに関連する数値コードとメタゲノムに関連する7桁のコードの最後の3桁(ファイル名の「.3」部分を除く)を追加したいと思います。コードのこの部分は大丈夫です。一度に1つのファイルしか処理できないことがわかります。

これが私が今持っている完全なコードです。これはうまくいきません。 (2つのテストファイルのうち1つでのみ動作します)

ls mgp*/mgm*.3/*.fna |  while read line ; do
        header=$(sed -r "s/^mgp([0-9]*)\/mgm[0-9]{4}([0-9]{1,})\.3\/(mgm.*\.fna)/\1_\2/") #this is where I get the code I want from the path
        sed -i.bak "s/^>/>${header}_/" $line  #this is where I add said code to my file
done

個別に見てみると、コードの一部が機能しているようです。書くなら

ls mgp*/mgm*.3/*.fna | while read line ; do
        echo $line
done

...その後、関心のある2つのテストファイルのパスを回復できました。私が書いた場合:

ls mgp*/mgm*.3/*.fna | while read line ; do
    echo $line
    header=$(sed -r "s/^mgp([0-9]*)\/mgm[0-9]{4}([0-9]{1,})\.3\/(mgm.*\.fna)/\1_\2/")
    echo $header
done

...そして何かかなり奇妙なことを発見しました。私は得る:

path for file#1
header for file #2

しかし、私は次のことを得ることを期待しています。

path for file#1
header for file#1
path for file#2
header for file#2

whileループの変数がどのように少し奇妙に動作するかについての以前の質問/回答を見たことがありますが、これを行うのに十分な理解がないようです。

ベストアンサー1

主な問題は、sed実行時に入力を提供しないことです。つまり、渡されたファイル名を含む周辺ループから継承されたstdinストリームを読み取りますls(最初の反復ですべて)。別の問題はリストファイルを使用していることですls(出力を正しく読むよりもファイル名を繰り返す方が簡単で安全ですls)。また、使用中のやや複雑な正規表現を考えると、コードを読むのは少し難しいです。


ファイルを繰り返すには、次のようにします。

for pathname in mgp*/mgm*.3/*.fna; do
   # ... use "$pathname" here ...
done

fastaファイルのパス名が与えられたら、サブディレクトリ名から3桁のゲノムコードを取得するには、次の手順を実行します$pathname

genome=${pathname%.3/*.fna}     # trim off tail
genome=${genome#mgp*/mgm????}   # trim off head

322たとえば、in $genomefrom mgp83581/mgm4729322.3/blah.fnainを指定します$pathname

同じ方法でプロジェクト番号を取得します。

project=${pathname%/mgm*.3/*.fna}   # trim off tail
project=${project#mgp}              # trim off head

それは$projectなる83581でしょ$genome322

>すべてのファスタファイルで行が開始されるたびにそれらを挿入するには、次の手順を実行します。

for pathname in mgp*/mgm*.3/*.fna; do
    genome=${pathname%.3/*.fna}     # trim off tail
    genome=${genome#mgp*/mgm????}   # trim off head

    project=${pathname%/mgm*.3/*.fna}   # trim off tail
    project=${project#mgp}              # trim off head

    sed -i .old "s/^>/>${project}_${genome}_/" "$pathname"
done

これにより、サフィックス付きの古いファイルも追加でバックアップされます.old

注: にコピーあなたのデータ。利用可能なfastaファイルがなく、最終ループをテストしていません。

おすすめ記事