複数のファイルの行を新しいファイルにコピーし、ファイル名を保持する方法は?

複数のファイルの行を新しいファイルにコピーし、ファイル名を保持する方法は?

(最大)53個のプロジェクトを含む.fasta形式の81個のファイルがあります。たとえば、

/User/MyData/Sample_1.fasta
/User/MyData/Sample_2.fasta
....
/User/MyData/Sample_81.fasta

各.fastaファイルには、次に区切られた名前IDと文字列が含まれています。

>AT1G00001
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>AT2G00002
AAAAATTTTGCCCGTGTGGGCCAAACTGTCATGCATGCACCGTACGTGCATGCAT
....
>ATXGXXXXX(up to 53)
AAACCCTCTTTGTGCCTGTGCATGCA

81個​​の.fastaファイル内の各文字列を新しい.fastaファイルにコピーして、次のようにします。

/User/MyData/AT1G00001.fasta
/User/MyData/AT2G00002.fasta
....
/User/MyData/ATXGXXXXX.fasta

そのうちの1つには次のものが含まれます(ディレクトリ内のすべての「Sample_X.fasta」ファイルからコピーした後)。

>Sample_1
ATCCACTGCTGTGTACCTGATCAGTGCTGACCCAYTGTGACACTGTG
>Sample_2
ATCGACTCCCGTAGGACTGATTTTTCTGACCCCATTGTGACACTGTG
....
>Sample_81
TTCTGACCCCATTGTGACACTGTGATCGACTCCCGTAGGACTGATTT

1つまたは2つの同様の問題に直面しましたが、コピーされた出力ファイルでSampleNameを保持する微妙な違いにはほとんど違いはありません。

助けてくれてありがとう!

答え1

次のコードがあります。以下にどのように機能するかについて説明します。

まず、作業ディレクトリ(cd /User/MyData/)を入力してプログラムを実行します。

awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { print ">" sample > target ; print > target }
' Sample_*.fasta

プログラムawkはすべてのファイルを繰り返しますSample_*.fasta。各入力ファイル()の先頭からFNR==1サフィックス「.fasta」を削除して、現在のファイル名からサンプル名を抽出します。行が始まる場合、>レコードのターゲットファイル名は>その文字の後にファイル名のサフィックス ".fasta"が追加されて使用されます。他の種類の行では、以前に抽出されたサンプル名がターゲットファイルに書き込まれ、現在のデータが2行目に書き込まれます。

注:「開いているファイル記述子が多すぎる」という問題が見つかった場合は、最良のオプションはGNUに切り替えることです(awk可能であれば)!

あなたのプラットフォームでGNUがawk利用できないか利用できない場合は、いくつかの追加の変更が必要です。重要なことは、各ファイルに書き込んだ後に閉じる機能を使用することですclose()。結果は閉じたファイルに追加する必要があります。 。 (これはより複雑でパフォーマンスが低下するため、GNUを入手してawk最初のバリアントを使用することを検討する価値があります。)

これらの変更により、次のプログラムが生成されます。

# because of the append operation you need to empty the file targets
# before calling subsequent awk code, e.g. by: rm -f AT???????.fasta
awk '
  FNR==1 { sample = FILENAME ; sub(/\.fasta/, "", sample }
  /^>/   { target = substr($0,2)".fasta" ; next }
         { printf ">%s\n%s\n", sample, %0 >> target ; close(target) }
' Sample_*.fasta

このawkプログラムを呼び出す前に、既存の出力ファイルが削除されたか、以前の呼び出しから消去されていることを確認する必要があります。それ以外の場合は、新しい出力が以前にその出力ファイルに存在していたデータに追加されます。

答え2

これまでに何を試したかを調べることも興味深いかもしれませんが、awkこれがどのように機能するかについての例は次のとおりです。

awk '
    FNR == 1 {
        sub(/\.fasta$/, "", FILENAME)
    }
    /^>/ && sub(/^>/, "") {
        newfile = $0 ".fasta"
        next
    }
    {
        print ">" FILENAME >> newfile
        print $0 >> newfile
    }' Sample_*.fasta

答え3

一部のシェル:awkプログラムよりはるかに遅いです。

cd /User/MyData
for sample in Sample*.fasta; do
    sample_name=${sample%.fasta}
    while read name; read data; do
        name=${name#>}
        printf ">%s\n%s\n" "$sample_name" "$data" >> "$name.fasta"
    done < "$sample"
done

関連情報