Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在两个文件之间搜索和替换-post#2_Regex_Perl - Fatal编程技术网

Regex 在两个文件之间搜索和替换-post#2

Regex 在两个文件之间搜索和替换-post#2,regex,perl,Regex,Perl,我需要用另一个文件中的information/regex替换一个文件中的变量。例如,我需要从file1中的每一行获取第一个字符串/变量(以MSTRG开头): MSTRG.5734 MSTRG.5734 509 -4 0 -14 0 0 MSTRG.19266 MSTRG.19266 842 -4 0 -12 0 0 MSTRG.26588 MSTRG.26588 196 5 0 12 0 0 并使用此选项在文件2中搜索,其外观如下所示: Chr1 S

我需要用另一个文件中的information/regex替换一个文件中的变量。例如,我需要从file1中的每一行获取第一个字符串/变量(以MSTRG开头):

MSTRG.5734  MSTRG.5734  509 -4  0   -14 0   0
MSTRG.19266 MSTRG.19266 842 -4  0   -12 0   0
MSTRG.26588 MSTRG.26588 196 5   0   12  0   0
并使用此选项在文件2中搜索,其外观如下所示:

Chr1    StringTie   transcript  24039360    24041181    1000    -   .   gene_id "MSTRG.5734"; transcript_id "MSTRG.5734.1"; 
Chr1    StringTie   transcript  24039810    24040595    1000    -   .   gene_id "MSTRG.5734"; transcript_id "Transcript:AT1G64700.1"; ref_gene_id "Gene:AT1G64700"
Chr1    StringTie   exon    24040560    24041181    1000    -   .   gene_id "MSTRG.19266"; transcript_id "MSTRG.19266.1"; exon_number "2"; 
Chr1    StringTie   exon    24040560    24041181    1000    -   .   gene_id "MSTRG.26588"; transcript_id "MSTRG.26588.1"; exon_number "2"; 
Chr1    StringTie   transcript  24039810    24040595    1000    -   .   gene_id "MSTRG.26588"; transcript_id "Transcript:AT5G41000.1"; ref_gene_id "Gene:AT5G41000";
理想情况下,当在文件2中的一行中找到例如
MSTRG.5734
,该行也包含字符串,例如
Gene:AT1G64700
,它将获取信息
Gene:AT1G64700
,并替换文件1中的
MSTRG.5734
。因此,文件1中每行上的每个
MSTRG
都是唯一的,理论上它将匹配文件2中的一个唯一基因。如果它与某个基因不匹配,则需要维护file1中的原始行

File1输出应如下所示:

    Gene:AT1G64700  MSTRG.5734  509 -4  0   -14 0   0
    MSTRG.19266 MSTRG.19266 842 -4  0   -12 0   0
    Gene:AT5G41000  MSTRG.26588 196 5   0   12  0   0
我当前的perl代码是:

use strict;
use warnings;
use vars qw($outfile @id $mstrg $gene);

open(SEARCH, $ARGV[0]) or die "Couldn't open $ARGV[0]: $!";
open(FILE, $ARGV[1]) or die "Couldn't open $ARGV[1]: $!";
$outfile = "testout.txt";
open (OUT, ">$outfile") || die "Can't open $outfile for creation: $!\n";

my %mstrg;

while (<SEARCH>) {
chomp;
if (/^MSTRG/) {
    chomp $_;
    @id = split (/\t/, $_);
        $mstrg{$id[1]}.="$id[1]";
 }
}
while (<FILE>) # {@ffn=<FILE>};
{
chomp ($gene=$_);
    if ($mstrg =~ /$gene/) {
    print OUT "$id[1]\t$id[2]";}
    else {
        #print OUT "$_\n";
            } 
next;
        }           

close FILE;
使用严格;
使用警告;
使用变量qw($outfile@id$mstrg$gene);
打开(搜索,$ARGV[0])或死亡“无法打开$ARGV[0]:$!”;
打开(文件$ARGV[1])或死亡“无法打开$ARGV[1]:$!”;
$outfile=“testout.txt”;
打开(OUT,“>$outfile”)| | die“无法打开$outfile进行创建:$!\n”;
我的%mstrg;
而(){
咀嚼;
如果(/^MSTRG/){
大口大口;
@id=拆分(/\t/,$);
$mstrg{$id[1]}.=“$id[1]”;
}
}
while()#{@ffn=};
{
chomp($gene=$);
如果($mstrg=~/$gene/){
打印出“$id[1]\t$id[2]”;}
否则{
#打印出“$\un”;
} 
下一个
}           
关闭文件;
不幸的是,我被困在这里,不知道如何继续?
感谢您给予我的帮助,感谢您对我之前的帖子表示的歉意,因为我没有向那些看到的人提供任何代码。

我会这样做:

use 5.014;               #needed min 5.014 because the /r modifier
use warnings;
use Path::Tiny '0.077';  #added the min. req. version

my $file1='file1.txt';
my $file2='file2.txt';

my %mstmap = map { split /\s+/, s/.*?gene_id\s*"\s*(MSTRG\.\d+).*ref_gene_id\s*"\s*(Gene:\w+)".*/$1 $2/r }
             grep { /ref_gene_id.*Gene:/ } path($file2)->lines({chomp => 1});
path($file1)->edit_lines( sub { s/^(MSTRG\.\d+)/exists($mstmap{$1}) ? $mstmap{$1} : $1/e });
为您的输入文件生成

Gene:AT1G64700  MSTRG.5734  509 -4  0   -14 0   0
MSTRG.19266 MSTRG.19266 842 -4  0   -12 0   0
Gene:AT5G41000 MSTRG.26588 196 5   0   12  0   0
它会为以下对创建一个哈希:
MSTRG.number
=>
Gene:String
(来自
file2
),并使用模块编辑功能在
file1
中进行替换

在@Borodin评论之后,上述内容可缩减为:

use 5.014;
use warnings;
use Path::Tiny '0.077';

my $file1='f1';
my $file2='f2';

my %mstmap = map {
    /.*?gene_id\s*"\s*(MSTRG\.\d+).*ref_gene_id\s*"\s*(Gene:\w+).*/
} path($file2)->lines({chomp => 1});
path($file1)->edit_lines( sub { s/^(MSTRG\.\d+)/exists($mstmap{$1}) ? $mstmap{$1} : $1/e });

没有必要编写坚不可摧的代码来实现您想要的结果

此程序从包含
mstrg.
Gene:
字符串的所有行中读取
$file2
构建哈希
%mstrg
。然后,它在
$re
中创建一个正则表达式,该正则表达式将匹配找到的任何一个
MSTR.
字符串

$file1
被打开,并且该正则表达式用于将任何哈希键替换为它出现在行首的相应哈希值。然后打印该行

现在还不清楚
file1.txt
的前两个字段是否总是相同的,但我选择只更改第一个字段

我使用了
autodie
pragma来避免显式检查任何文件IO操作是否成功

程序将输出打印到STDOUT,这样您就可以在命令行上将其重定向到任何地方

使用严格;
使用“全部”警告;
使用自动模具;
my($file1,$file2)=@ARGV;
我的%mstrg;
{

打开我的$fh,'Wow@jm666。在./test.pl第12行的散列赋值中获取一个错误
奇数个元素。(即grep…)无法通过包“Path::Tiny”找到对象方法“edit_line”在./test.pl第13行。
谢谢,不过,我会花更多的精力看看我是否能找出错误的原因。我想我没有安装它:)谢谢@jm666,我会继续努力,看看我能从哪里得到。
映射{split/\s+/,s/*?gene\u id\s*“\s*(MSTRG\。+。。.*ref_gene\u-gene\u-id\s*”“\s*(gene:\w+)。*/$1$2/r}
通常写为
map{/*?gene\u id\s*“\s*(MSTRG\.\d+).*ref\u gene\u id\s*”\s*(gene:\w+)。*/}
。这样就不需要使用
grep
。谢谢@Borodin-这显然是我级别的代码。我遇到了一个我不熟悉的错误-不知道你是否知道发生了什么,否则我会尽力弄清楚。“无法打开”阅读:“没有这样的文件或目录”`这是refe这行代码
打开我的$fh,“@jnorth:目前它使用与您自己的代码相同的方案:到file1和file2的路径是命令行参数。我猜您没有传递任何参数。天哪,我不觉得很傻-我在代码上花了这么多时间才把它拿出来,没有想到把它放回去……谢谢获得@Borodin!@jnorth:你只需要复制我的代码并运行它就可以了。