【问题标题】:Find specific text in many lines with Perl使用 Perl 在多行中查找特定文本
【发布时间】:2016-04-23 22:16:10
【问题描述】:

我正在尝试在数千行的文件中查找所有出现的字母字符串。然后我将计算每个字符串。下面的示例文件仅包含两行,但该文件中的所有文本都是相同的结构(其中> 表示新行,而字母字符串是要搜索的位置。截至目前,我将整个文件作为输出返回不仅仅是我要找的字符串。谢谢:)。

文件

>hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGGTTCGGGCGATGCTGCAGGgtgagagggagcccagcggtgcggtgggg

g 的期望输出{4}

gggg

g 的期望输出{3}

GGG
GGG
ggg
ggg

Perl 我试过了

{...} 之间的4 是要搜索的qw(G g) 的数量)

cat file.txt | perl -ne 'chomp; s/\s|\cJ|\cM//g; s/^\>/\n/ and $_.="\t";print' | perl -ne '$in=$_;grep $in=~m/$_{4}/i, qw(G g) and print' > test.txt

编辑

>hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGGTTCGGGCGATGCTGCAGGgtgagagggagcccagcggtgcggtgggg
>hg19_refGene_NM_001282675 range=chr11:35453376-35551848 5'pad=0 3'pad=0 strand=- repeatMasking=none
TTCATTAGGGCTGGAGACTTCCATGAAGGGGCCAGTTACAGCAGGCTCCA

多个输出(搜索所在的行并输出)

>hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGG
GGG
GGg
ggg
ggg
>hg19_refGene_NM_001282675 range=chr11:35453376-35551848 5'pad=0 3'pad=0 strand=- repeatMasking=none
GGG
GGG
GGG

我得到多个输出

  perl -076 -nE 'chomp; s/(.+)// && say qq{>$1}; s/\s//g; say $1 while /(g{3})/gi' 4G.txt

 >hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGG
GGG
GGg
ggg
ggg
>hg19_refGene_NM_001282675 range=chr11:35453376-35551848 5'pad=0 3'pad=0 strand=- repeatMasking=none
GGG
GGG

【问题讨论】:

  • 您的样本序列中间有一个GGg。这不算吗?当文件中有多个序列时,你想要什么输出?

标签: perl


【解决方案1】:

从表面上看,这很简单。这种单线产生的东西就像你说你想要的一样

perl -nE'/^>/ or say $1 while /(g{3})/ig' test.txt

输出

GGG
GGG
GGg
ggg
ggg

但是,正如我在评论中所说,尚不清楚 GGg 是否算数,并且您没有说当文件中有多个序列时会发生什么



更新

这将解决修改后的问题

perl -nE'/^>/ and print or do { say $1 while /(g{3})/ig}' test.txt

输出

>hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGG
GGG
GGg
ggg
ggg
>hg19_refGene_NM_001282675 range=chr11:35453376-35551848 5'pad=0 3'pad=0 strand=- repeatMasking=none
GGG
GGG



更新 2

这修复了包含行尾的子序列。这与我真正想要的单线解决方案一样复杂

perl -076 -nE 'chomp; s/(.+)// && say qq{>$1}; s/\s//g; say $1 while /(g{3})/gi' test.txt

输出

>hg19_refGene_NM_000016 range=chr1:76190032-76229363 5'pad=0 3'pad=0 strand=+ repeatMasking=none
GGG
GGG
GGg
ggg
ggg
>hg19_refGene_NM_001282675 range=chr11:35453376-35551848 5'pad=0 3'pad=0 strand=- repeatMasking=none
GGG
GGG

【讨论】:

  • 我为多行添加了一个编辑,甚至没有看到 GGg,但是你是对的,它确实很重要。电脑犯的错误比我少:)...谢谢:)。
  • 对多个条目进行编辑有帮助吗?谢谢你:)。
  • 好的,我已经解决了。 (除了第二个项目中只有两个ggg 子序列,而不是你说的三个。)另一个问题是,如果子序列在文件中被分割成多行,你是否需要计算子序列?目前ggg如果文件中包含"xxxgg\ngxxxx\n"这样的行,将不会被找到
  • 我已经发布了我从命令获得的输出,并且是的子序列用于计数,如您所说明的。谢谢你:)。
  • @Chris:抱歉,我忘记转换为 Linux 命令行语法了。我已经更新了
【解决方案2】:

如果您单独使用一个perl 进程(没有cat),您可以使用“嵌套while”语句从数据文件“while()”中读取一行,它是打开的并且有行剩下要读的,然后print匹配的元素“while()”这行有匹配的东西:

 perl -e 'use English; 
          while(<>) { print "$MATCH\n" while $_ =~ /g{3}/ig }'
          sequence.txt

$MATCH$&amp;。我添加了 use English 用于说明目的 ;-) ...)


编辑:

嵌套的while() 方法正是@Borodin 的答案所做的,因为它使用-n 开关,正如perldoc perlrun 告诉我们的那样,用while(&lt;&gt;){} 包装-E 之后的语句。

【讨论】:

  • use English 单线有点疯狂!
  • :-D 同意...只要把它放在那里以防$1 不清楚...我没有看到使用$1 的OP ...我经常使用perl来自 shell 的命令,在使用 -E-n 时,最终与“单线”并不完全相同。我必须说我不知道​​我为什么要这样做! ... TIMTOWDI 也许:-D
  • 你知道$MATCH$&amp; 是一样的,对吧?不是$1
  • @Borodin doh!修复了它,但我猜 $&amp; 不是 perls 的最佳方式
猜你喜欢
  • 2013-11-28
  • 1970-01-01
  • 2016-06-29
  • 2016-08-21
  • 2013-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多