Bash 使用awk提取两个单独的字符串

Bash 使用awk提取两个单独的字符串,bash,unix,awk,grep,bioinformatics,Bash,Unix,Awk,Grep,Bioinformatics,MacOS,Unix 因此,我有一个以下斯德哥尔摩格式的文件: # STOCKHOLM 1.0 #=GS WP_002855993.1/5-168 DE [subseq from] MULTISPECIES: AAC(3) family N-acetyltransferase [Campylobacter] #=GS WP_002856586.1/5-166 DE [subseq from] MULTISPECIES: aminoglycoside N(3)-acetyltransferase

MacOS,Unix

因此,我有一个以下斯德哥尔摩格式的文件:

# STOCKHOLM 1.0

#=GS WP_002855993.1/5-168 DE [subseq from] MULTISPECIES: AAC(3) family N-acetyltransferase [Campylobacter]
#=GS WP_002856586.1/5-166 DE [subseq from] MULTISPECIES: aminoglycoside N(3)-acetyltransferase [Campylobacter]

WP_002855993.1/5-168         ------LEHNGKKYSDKDLIDAFYQLGIKRGDILCVHTELmkfgKALLT.K...NDFLKTLLECFFKVLGKEGTLLMP-TF---TYSF------CKNE------VYDKVHSKG--KVGVLNEFFRTSGgGVRRTSDPIFSFAVKGAKADIFLKEN--SSCFGKDSVYEILTREGGKFMLLGLNYG-HALTHYAEE-----
#=GR WP_002855993.1/5-168 PP ......6788899999***********************9333344455.6...8999********************.33...3544......4555......799999975..68********98626999****************999865..689*********************9875.456799996.....
WP_002856586.1/5-166         ------LEFENKKYSTYDFIETFYKLGLQKGDTLCVHTEL....FNFGFpLlsrNEFLQTILDCFFEVIGKEGTLIMP-TF---TYSF------CKNE------VYDKINSKT--KMGALNEYFRKQT.GVKRTNDPIFSFAIKGAKEELFLKDT--TSCFGENCVYEVLTKENGKYMTFGGQG--HTLTHYAEE-----
#=GR WP_002856586.1/5-166 PP ......5566677788889999******************....**9953422246679*******************.33...3544......4455......799998876..589**********.******************99999886..689******************999765..5666***96.....
#=GC PP_cons                 ......6677788899999999*****************9....77675.5...68889*******************.33...3544......4455......799999976..689*******998.8999**************99999876..689******************9998765.466699996.....
#=GC RF                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx.x...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

WP_002855993.1/5-168         -----------------------------------------------------------------------------------------------------
#=GR WP_002855993.1/5-168 PP .....................................................................................................
WP_002856586.1/5-166         -----------------------------------------------------------------------------------------------------
#=GR WP_002856586.1/5-166 PP .....................................................................................................
#=GC PP_cons                 .....................................................................................................
#=GC RF                      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//
我已经创建了一个脚本来提取我想要的ID,在本例中是WP_002855993.1和WP_002856586.1,并搜索另一个文件以提取具有适当ID的DNA序列。脚本如下:

#!/bin/bash

for fileName in *.sto;
do
protID=$(grep -o "WP_.\{0,11\}" $fileName | sort | uniq)
echo $protID
file=$(echo $fileName | cut -d '_' -f 1,2,3)
file=$(echo $file'_protein.faa')
echo $file 
if [ -n "$protID" ]; then
gawk "/^>/{N=0}/^.*$protID/{N=1} {if(N)print}" $file >> 
sequence_protein.file
fi
done
下面是我正在查看的文件类型的一个示例:

>WP_002855993.1 MULTISPECIES: AAC(3) family N-acetyltransferase [Campylobacter]
MKYFLEHNGKKYSDKDLIDAFYQLGIKRGDILCVHTELMKFGKALLTKNDFLKTLLECFFKVLGKEGTLLMPTFT
>WP_002856586.1 MULTISPECIES: aminoglycoside N(3)-acetyltransferase [Campylobacter]
MKYLLEFENKKYSTYDFIETFYKLGLQKGDTLCVHTELFNFGFPLLSRNEFLQTILDCFFEVIGKEGTLIMPTFT
YSFCKNEVYDKINSKTKMGALNEYFRKQTGVKRTNDPIFSFAIKGAKEELFLKDTTSCFGENCVYEVLTKENGKY
>WP_002856595.1 MULTISPECIES: acetyl-CoA carboxylase biotin carboxylase subunit [Campylobacter]
MNQIHKILIANRAEIAVRVIRACRDLHIKSVAVFTEPDRECLHVKIADEAYRIGTDAIRGYLDVARIVEIAKACG

如果我有一个ID,这个脚本就可以工作,但在某些情况下,我会得到两个ID,并得到一个错误,因为我认为它正在寻找一个类似“WP_002855993.1 WP_002856586.1”的ID。是否有方法修改此脚本,使其查找两个单独的事件?我猜这是因为gawk命令,但我不确定到底是什么。提前谢谢

考虑到您的输出文件是测试文件

使用以下命令仅提供文件名:

>>cat text | awk '{print $1}' | grep -R 'WP*' | cut -d":" -f2
给我输出:

WP_002855993.1/5-168
WP_002856586.1/5-166
WP_002855993.1/5-168
WP_002856586.1/5-166

您想要这样的输出吗?

原始脚本的更新:

#!/usr/bin/env bash

for file_sto in *.sto; do
   file_faa=$(echo $file_sto | cut -d '_' -f 1,2,3)
   file_faa=${file_faa}"_protein.faa"

   awk '(NR==FNR) { match($0,/WP_.\{0,11\}/);
                    if (RSTART > 0)  a[substr($0,RSTART,RLENGTH)]++ 
                    next; }
        ($1 in a){ print RS $0 }' $file_sto RS=">" $file_faa >> sequence_protein.file
done
awk
部件甚至可能减少为:

awk '(NR==FNR) { if ($0 ~ /^WP_/) a[$1]++; next }
     ($1 in a) { print RS $0 }' FS='/' $file_sto FS=" " RS=">" $file_faa
awk
脚本执行以下操作:

  • 将字段分隔符
    FS
    设置为
    /
    并读取文件
    $file\u sto
  • 读取
    $file\u sto
    时,记录编号
    NR
    与文件记录编号
    FNR
    相同
  • (NR==FNR){if($0~/^WP_/)a[$1]+;next}
    :由于前面的条件,此行只能运行一个
    $file_sto
    。它检查行是否以
    WP\uwp
    开头。如果是,它将第一个字段
    $1
    (由
    FS
    分隔,后者是
    /
    )存储在数组
    a
    中;然后跳转到文件中的下一条记录(
    next
  • 如果我们读取完文件
    $file\u sto
    ,我们将字段分隔符设置回单个空格
    FS=”“
    (请参阅)记录分隔符
    RS
    并开始读取文件
    $file\u faa
    ,后者意味着
    $0
    将包含
    之间的所有行,第一个字段
    $1
    protID
  • 读取
    $file\u faa
    ,文件记录编号
    FNR
    从1重新启动,而
    NR
    未重置。因此,将跳过第一行
    awk
  • (a中的$1){print RS$0}
    如果第一个字段在数组
    a
    中,请使用前面的记录分隔符打印该记录
  • 修复原始脚本:

    #!/usr/bin/env bash
    
    for file_sto in *.sto; do
       file_faa=$(echo $file_sto | cut -d '_' -f 1,2,3)
       file_faa=${file_faa}"_protein.faa"
    
       awk '(NR==FNR) { match($0,/WP_.\{0,11\}/);
                        if (RSTART > 0)  a[substr($0,RSTART,RLENGTH)]++ 
                        next; }
            ($1 in a){ print RS $0 }' $file_sto RS=">" $file_faa >> sequence_protein.file
    done
    
    如果要保留原始脚本,可以将
    protID
    存储在列表中,然后循环列表:

    #!/bin/bash
    
    for fileName in *.sto; do
        protID_list=( $(grep -o "WP_.\{0,11\}" $fileName | sort | uniq) )
        echo ${protID_list[@]}
        file=$(echo $fileName | cut -d '_' -f 1,2,3)
        file=$(echo $file'_protein.faa')
        echo $file 
        for protID in ${protID_list[@]}; do
           if [ -n "$protID" ]; then
              gawk "/^>/{N=0}/^.*$protID/{N=1} {if(N)print}" $file >> 
              sequence_protein.file
           fi
        done
    done
    

    谢谢,原稿的修改版作品!我知道我对awk的使用不是很优雅,所以也谢谢你的选择!我有点新,所以我还没有完全理解代码,但是在输出文件中,如果我使用reduced awk命令,它会给出.sto文件和.faa文件中的序列。有没有简单的解决方法,所以我只是从.faa文件中获取序列?@D.Parker我有一个小错误。我已经更新了代码。我还将对此做一些解释。@D.Parker我已经添加了一些评论。还有,别忘了