根据某些模式将文件拆分为多个文件并获取一些信息

时间:2016-12-13 15:07:57

标签: database bash awk sh

我正在使用这种结构的许多文件:

BEGIN
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=1393
PEPMASS=946.3980102539062
CHARGE=3.0+
USER03=
SEQ=DDDIAAL
TAXONOMY=9606
272.228 126847.000
273.252 33795.000
END

BEGIN IONS
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=1383
PEPMASS=911.3920288085938
CHARGE=2.0+
USER03=
SEQ=QGKFEAAETLEEAAMR
TAXONOMY=9606
1394.637    71404.000
1411.668    122728.000
END

BEGIN IONS
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=2965
PEPMASS=946.3900146484375
CHARGE=3.0+
TAXONOMY=9606
1564.717    92354.000
1677.738    33865.000
END

此结构重复数千次,但内部数据不同。正如您所看到的,在某些开始端之间,有时SEQ和USER03不存在。这是因为蛋白质未被识别......这就是我的问题。

我想知道有多少蛋白质被识别出来,有多少蛋白质被识别出来。要做到这一点,我试着这样做:

for i in $(ls *.txt ); do
    echo $i

    awk '/^BEGIN/{n++;w=1} n&&w{print > "./cache/out" n ".txt"} /^END/{w=0}' $i

done

我在这里找到了这个(Split a file into multiple files based on a pattern and name the new files by the search pattern in Unix?

然后使用输出并对它们进行分类:

for i in $(ls cache/*.txt ); do
    echo $i

    if grep -q 'SEQ' $i; then
        mv $i ./archive_identified
    else
        mv $i ./archive_unidentified
    fi
done

在此之后,我想从分类文件中获取一些数据(例如:spectrum,USER03,SEQ,TAXONOMY)。

for I in $( ls archive_identified/*.txt ); do
    echo $i
    grep 'SEQ' $i | cut -d "=" -f2- | tr ',' '\n' >> ./sequences_ide.txt
    grep 'TAXONOMY' $i | cut -d "=" -f2- | tr ',' '\n' >> ./taxonomy_ide.txt
    grep 'USER' $i | cut -d "=" -f2- >> ./modifications_ide.txt
    grep 'TITLE' $i | sed 's/^.*\(spectrum.*\)/\1/g' | cut -d "=" -f2-  >> ./spectrum.txt

done

for i in $( ls archive_unidentified/*.txt ); do
    echo $i
    grep 'SEQ' $i | cut -d "=" -f2- | tr ',' '\n' >> ./sequences_unide.txt
    grep 'TAXONOMY' $i | cut -d "=" -f2- | tr ',' '\n' >> ./taxonomy_unide.txt
    grep 'USER' $i | cut -d "=" -f2- >> ./modifications_unide.txt
    grep 'TITLE' $i | sed 's/^.*\(spectrum.*\)/\1/g' | cut -d "=" -f2-  >> ./spectrum_unide.txt

done

问题是由于数据量很大(12-15gb),脚本的第一部分需要花费太多时间。有没有办法更轻松地做到这一点?

提前谢谢你。

1 个答案:

答案 0 :(得分:2)

您可以在一个awk脚本中执行所有操作。 awk可以遍历所有行(记录),因此您不需要外部循环。例如,对于您提供的数据文件

$ awk -v RS= '/\nSEQ/ {seq++;   print > "file_path_with_seq" NR ".txt"; next} 
                      {noseq++; print > "file_path_without_seq" NR ".txt"} 
                 END  {         print "with seq:", seq; 
                                print "without seq:", noseq}' file

将打印

with seq: 2
without seq: 1

并生成文件

$ head file_path_with*

==> file_path_with_seq1.txt <==
BEGIN
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=1393
PEPMASS=946.3980102539062
CHARGE=3.0+
USER03=
SEQ=DDDIAAL
TAXONOMY=9606
272.228 126847.000
273.252 33795.000
END

==> file_path_with_seq2.txt <==
BEGIN IONS
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=1383
PEPMASS=911.3920288085938
CHARGE=2.0+
USER03=
SEQ=QGKFEAAETLEEAAMR
TAXONOMY=9606
1394.637    71404.000
1411.668    122728.000
END

==> file_path_without_seq3.txt <==
BEGIN IONS
TITLE=id=PRD000012;PRIDE_Exp_Complete_Ac_1645.xml;spectrum=2965
PEPMASS=946.3900146484375
CHARGE=3.0+
TAXONOMY=9606
1564.717    92354.000
1677.738    33865.000
END