Linux 提取包含两个模式的行

Linux 提取包含两个模式的行,linux,awk,grep,fasta,Linux,Awk,Grep,Fasta,我有一个包含以下几行的文件: >header1 <pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2> >header2 <pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCA

我有一个包含以下几行的文件:

>header1
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2>
>header2
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_2>
>header3
<pattern_1>ATGGCCACCAACAACCAGAGCTCCC
>header4
GACCGGCACGTACAACCTCCAGGAAATCGTGCCCGGCAGCGTGTGGATGGAGAGGGACGTG
>header5
TGCCCCCACGACCGGCACGTACAAC<pattern_2>
>标题1
CGGCGGGCAGATGCCACACACACACACAGCAGGCCTCCCTGGCCGGGCCTTTTCGTAGCGGCCGCCCCCCCACTGCCCCCCCCCCCCCGCTACAAC
>校长2
CGGCGGGCAGATGCCACACACACACACAGAGCTCTCTCTCTCTCTCTCTCCGTGTTTCACACACACGCCACTGCCCCACACACACACACACACACACACACAGAGCTCTCTCTCTCTCTCTCTCTCTCTCCGTGTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCCCCACACACACACACA
>校长3
ATGGCCACACCAGGCTCCC
>校长4
GACCGGCACGTACACCTCGAGAATCGTGCCCGGCAGCGGTGGATGGAGAGAGAGGACGTG
>校长5
TGCCCCGACCGGCACGTACAC
我想提取所有既包含标题行又包含标题行的行

grep <pattern_1> | grep <pattern_2> input.fasta > output.fasta
我尝试过使用grep,但它只提取序列行,而不提取标题行

grep <pattern_1> | grep <pattern_2> input.fasta > output.fasta
grep | grep input.fasta>output.fasta
如何在Linux中提取同时包含模式和标题的行?这些图案可以出现在线条的任何地方。不限于线路的起点或终点

预期产出:

>header1
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2>
>header2
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_2>
>标题1
CGGCGGGCAGATGCCACACACACACACAGCAGGCCTCCCTGGCCGGGCCTTTTCGTAGCGGCCGCCCCCCCACTGCCCCCCCCCCCCCGCTACAAC
>校长2
CGGCGGGCAGATGCCACACACACACACAGAGCTCTCTCTCTCTCTCTCTCCGTGTTTCACACACACGCCACTGCCCCACACACACACACACACACACACACAGAGCTCTCTCTCTCTCTCTCTCTCTCTCCGTGTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCCCCACACACACACACA

如果您希望grep打印比赛前后的各行,请在比赛前使用-B标志,在比赛后使用-A标志,在比赛前后使用-C标志

在您的情况下,grep-b1似乎可以完成这项工作

$ grep -A 1 header[12] file
>header1
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2>
>header2
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_2>

grep-b1模式[12]
也可以工作,但在示例数据中有几个
pattern\u1
s,因此。。。这次不行。

您可以用awk轻松做到这一点,如下所示:

awk '/^>/{h=$0;next}
     /<pattern_1>/&&/<pattern_2>/{print h;print}' input.fasta > output.fasta
awk'/^>/{h=$0;next}
//&&//{print h;print}'input.fasta>output.fasta
这是一个sed解决方案,它也可以产生所需的输出:

sed -n '/^>/{N;/<pattern_1>/{/<pattern_2>/p}}' input.fasta > output.fasta
sed-n'/^>/{n;/{//{p}}input.fasta>output.fasta

如果可能存在多行记录,可以使用以下方法:

awk -v pat1='<pattern_1>' -v pat2='<pattern_2>' '
/^>/ {r=$0;p=0;next}
!p {r=r ORS $0;if(chk()){print r;p=1};next}
p

function chk(   tmp){
    tmp=gensub(/\n/,"","g",r)
    return (tmp~pat1&&tmp~pat2)
}' input.fasta > output.fasta
awk-v pat1='''-v pat2=''
/^>/{r=$0;p=0;next}
!p{r=r或$0;if(chk()){print r;p=1};next}
P
功能chk(tmp){
tmp=gensub(/\n/,“”,“g”,r)
返回(tmp~pat1和&tmp~pat2)
}'input.fasta>output.fasta

如果您的输入文件与文章中描述的完全相同,那么您可以使用:

grep -B1 '^<pattern_1>.*<pattern_2>$' input 
>header1
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2>
>header2
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_2>
输出:

grep -B1 '^.*<pattern_1>.*<pattern_2>.*$\|^.*<pattern_2>.*<pattern_1>.*$' input 
>header1
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCGGGCCTCTTTTCCTGACGGCCGCCCCCACTGCCCCCACGACCGGCCCGTACAAC<pattern_2>
>header2
<pattern_1>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_2>
>header2b
<pattern_2>CGGCGGGCAGATGGCCACCAACAACCAGAGCTCCCTGGCCTGCAATCACTACTCGTGTTTTGCCACCACTGCCCCCACGACCGGCACGTACAAC<pattern_1>
grep-B1'^.*$\\\\124;^.*$'输入
>校长1
CGGCGGGCAGATGCCACACACACACACAGCAGGCCTCCCTGGCCGGGCCTTTTCGTAGCGGCCGCCCCCCCACTGCCCCCCCCCCCCCGCTACAAC
>校长2
CGGCGGGCAGATGCCACACACACACACAGAGCTCTCTCTCTCTCTCTCTCCGTGTTTCACACACACGCCACTGCCCCACACACACACACACACACACACACAGAGCTCTCTCTCTCTCTCTCTCTCTCTCCGTGTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCCCCACACACACACACA
>标题2B
CGGCGGGCAGATGCCACACACACACACAGAGCTCTCTCTCTCTCTCTCTCCGTGTTTCACACACACGCCACTGCCCCACACACACACACACACACACACACAGAGCTCTCTCTCTCTCTCTCTCTCTCTCCGTGTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCTCCCCACACACACACACA

您可能会感兴趣,它是经过调整的awk版本,可以处理fasta文件

bioawk -c fastx -v seq1="pattern1" -v seq2="pattern2" \
       '($seq ~ seq1) && ($seq ~ seq2) { print ">"$name; print $seq }' file.fasta
如果您希望在开始时使用
seq1
,在结束时使用
seq2
,可以将其更改为:

bioawk -c fastx -v seq1="pattern1" -v seq2="pattern2" \
       '($seq ~ "^"seq1) && ($seq ~ seq2"$") { print ">"$name; print $seq }' file.fasta
这对于处理fasta文件非常实用,因为序列通常分布在多行上。上面的代码很容易处理这个问题,因为变量
$seq
包含完整的序列

如果不想安装BioAwk,可以使用以下方法处理FASTA文件。它将允许多行序列,并执行以下操作:

  • 一次读取一条记录(假设标题中没有
    ,第一个字符除外)
  • 从记录中提取标题并将其存储在
    name
    (实际上不需要)
  • 在单个字符串中合并完整序列,删除所有换行符和空格。这确保了如果将模式拆分为多行,则搜索
    pattern1
    pattern2
    不会失败
  • 如果找到匹配项,则打印记录
以下awk执行请求的操作:

awk -v seq1="pattern1" -v seq2="pattern2" \
    'BEGIN{RS=">"; ORS=""; FS="\n"}
     { seq="";for(i=2;i<=NF;++i) seq=seq""$i; gsub(/[^a-zA-Z0-9]/,"",seq) }
     (seq ~ seq1 && seq ~ seq2){print ">" $0}' file.fasta
注意:如果fasta文件中引入了意外字符(例如空格/制表符或
CR
\r
),我们在此处使用
sub



注意:基于中记录的。我不确定此版本是否与兼容。

我想提取包含这两行并包括标题行的所有行。对我来说毫无意义。请为该输入添加预期的输出(或更具体地说)。可能需要其他选项吗<代码>grep-E“pattern | header”文件请注意fasta文件可能具有多行序列。多记录解决方案无效。fasta文件中的多行表示一个序列,该序列被拆分为多行以便于读取(80个字符宽),我相信在这种情况下,应该在完整的多行序列中的某个位置。解决方案仍然无效,因为
pattern1
pattern2
可以拆分为多行。@kvantour Ok我放弃了that@kvantour我喝醉了。但我会努力的later@kvantour再次更新。不能再往前走了。Tks分享Awk书籍。@OXO请注意,这是一本非常古老的书,只是写下来作为参考。更好的书可以在Tks上找到,以供参考。克万图尔
awk -v seq1="pattern1" -v seq2="pattern2" \
    'BEGIN{RS=">"; ORS=""; FS="\n"}
     { seq="";for(i=2;i<=NF;++i) seq=seq""$i; gsub(/[^a-zA-Z0-9]/,"",seq) }
     (seq ~ seq1 && seq ~ seq2){print ">" $0}' file.fasta
awk -v seq1="pattern1" -v seq2="pattern2" \
    '/^>/ && (seq ~ seq1 && seq ~ seq2) {
         print name
         for(i=0;i<n;i++) print aseq[i]
     }
     /^>/ { seq=""; delete aseq; n=0; name=$0; next }
     { aseq[n++] = $0; seq=seq""$0; sub(/[^a-zA-Z0-9]*$/,"",seq) }
     END { if (seq ~ seq1 && seq ~ seq2) {
              print name
              for(i=0;i<n;i++) print aseq[i]
            }
     }' file.fasta