複数のファイルの行を1つのファイルにコピーし、その行の名前を元のファイル名として指定する方法

複数のファイルの行を1つのファイルにコピーし、その行の名前を元のファイル名として指定する方法

私の問題は、fata形式のファイルが200個あることです。たとえば、

 /User/Bin/bin.0.fa
 /User/Bin/bin.1.fa
 ...
 /User/Bin/bin.200.fa

各.faファイルには、ヌクレオチド文字で区切られた連続した名前IDが含まれています。

In /User/Bin/bin.0.fa

>c_000000000001
CGACATTTTCCAACTTATTTTTTCCTGTAGTAAAAATTATTTACATACAAAAAAGGAGCTGTTCACTAATTATTTAGTGC
>c_000000000002 
TACAACTCCTTTTTACTATTCTTCTGAATTTGATTTTTCATCCATTTGTTTTTGAGCTTCTTGAACTAATTTATCAAGACTATTATCTTCTACAACTTCATTTTCTTGTCTATCTAATTCATCTGTTAATGTTAATTGCTGATCTTTATCTTCTACATCT CTACCTGAAATTTTAGCTATAGCTACAATCTTTTCTTCATCAGAAGTTCTCATTAATCTAACTCCCATTGTAGCTCTAC
>c_000000000003  
AGTTACAGATACATCTGATACATTAATTCTTATAGCAACACCACTTGTATTTATAAGCATTAATTCATCTTCAGATTTACATACTGTTGCACCAACAACTTTACCAGTCTTTTCACTGATTTTGTATGTTATTAAACCAACTCCACCTCTATTTTGTCTC
...

In /User/Bin/bin.1.fa

>c_000000000004
GGATCATCGCTTGTACATCCCAAACCAAAAAAGAATACTGCACTTACAATCAGTTGGATTTGAAACGCGATTTTCATTTTTGGTATATGTTTAAGATTAGCACTTTGTTTCATTGCTTTTGGCTATGAACGATGTTTACGGGGGTGTA
>c_000000000005 
GAAAGAAGCGTATTGGTCGGTATAAATACCGCTCAACTAAACGAGCACAAAGCTACCGAAAATTTGGATGAATTGGCTTTTCTGGCCCAAACGGCTGGAGC
>c_000000000006
CGGCACTTATTTGCCCCAGCCCATTTTGGGGGTAGAAATACCCAAGAGCAAGGGAAAGGTTCGCCTTCTGGGTGTGCCTACCGTGGTTGACCGTATGTTGCAAC
... 

...
In /User/Bin/bin.200.fa

>c_000000020120   
CTCTGCAACTGGATCCCGAAAAGATCCGCAAAGAAAGCGAACCCAAAGAAAAAGTCGATCTGGAGAGCACCGTCGCCCGCAGTCTGGCCACCCT
>c_000000020121
CATCAATCATCTCAAATACTACCGCAACGCAGATTATTCCCAGTGCAATAACAAAACCGACTCCCGCCTCTTTTGTCTGGCCGTA
>c_000000050122 
GGTACGCCTCCGGCAGAACAAGGCGGCAACGAACCTCAGAACGAGGGAAAGCTAACCCAGGCCGGGTACGCCTCCGGCAGAACAAGGCGGCAACGAACCTCAGAACGAGGGAAAGCTAACCCAGGCCG
...  

特定の.faファイルの各contig名ID(">"を除く)を単一のタブで区切られたtxtファイルにコピーしたいと思います。ここで、contig name ID の名前はソースファイル n+1 で指定されます。このように:

In /User/Bin/Summary.txt

c_000000000001 Bin_1
c_000000000002 Bin_1
c_000000000003 Bin_1
...
c_000000000004 Bin_2
c_000000000005 Bin_2
c_000000000006 Bin_2
...
...
c_000000020120 Bin_201
c_000000020121 Bin_201
c_000000020122 Bin_201

答え1

公開された入力/出力の例と許可された答えを考慮すると、実際に必要なのはARGINDにGNU awkを使用することだけです。

awk -F'>' -v OFS='\t' 'NF>1{print $2, "Bin_"ARGIND}' /Usr/Bin/bin*.fa > /User/Bin/Summary.txt

または awk を使用してください。

awk -F'>' -v OFS='\t' 'FNR==1{++c} NF>1{print $2, "Bin_"c}' /Usr/Bin/bin*.fa > /User/Bin/Summary.txt

答え2

#!/usr/bin/env python

import os

files = os.listdir('/User/Bin')
for file in files:
    fi = open(file, 'r')
    n = file.split('.')[1]
    for line in fi:
        line = line.strip()
        if line.startswith('>'):
            bins = 'Bin_' + n
            print("%s\t%s" % (line[1:], bins))
    fi.close()

Linuxを使用している限り、Pythonがインストールされているはずです。これは効果があるかもしれません。

答え3

これを実行できるコマンドは次のとおりです。

grep "^>" /User/Bin/*.fa | awk -F ":>|\\." '{sub(".*/", "", $1);printf "%s\t%s_%d\n",$4,$1,$2+1}'

手順を説明します

grep "^>" /User/Bin/*.fa

上記のコマンドは、目的のパターンを持つ行のみを識別し、それに応じてファイル名を印刷します。 awkを使用して一致する行を印刷することもできますが、grepを使用するとファイル名に必要な操作を簡単に実行できます。

awk -F ":>|\\." 

これにより、「:>」文字または「.」がフィールド区切り文字として機能し、grepの出力が4つの部分に分割されます。 1.ファイル名の最大最初の「。」 2. インデックス名 3. 拡張子 4. 実際の grep モデル

{sub(".*/", "", $1)

上記の手順では、ファイル名の最初の部分からデフォルト名を削除します。

printf "%s\t%s.%d\n",$4,$1,$2+1}

必要に応じて2番目の部分を1ずつ増やし、タブを区別するためにタブを挿入する最終印刷を行います。

答え4

代替awk grep組み合わせ

grep -Eo "c_[0-9]+" *.fa | awk -F'[.:]' '{print $4,"Bin_"$2+1}' | column -t

または

grep -Eo "c_[0-9]+" *.fa | awk -F'[.:]' 'BEGIN{OFS="\t"}{print $4,"Bin_"$2+1}'

または常に「bin...」でない場合

grep -Eo "c_[0-9]+" *.fa | awk -F'[.:]' 'BEGIN{OFS="\t"}{print $4,toupper(substr($1,1,1))substr($1,2)"_"$2+1}'

grep入力ファイルが1つしかない場合、この使用は失敗します。この場合、この-Hオプションを使用する必要があります。

関連情報