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 perl多行查找和替换_Regex_Perl_Sed_Awk_Multiline - Fatal编程技术网

Regex perl多行查找和替换

Regex perl多行查找和替换,regex,perl,sed,awk,multiline,Regex,Perl,Sed,Awk,Multiline,我尝试在以下输入上使用简单的perl one liner: @F7##########0/1 C4CTA6GCAAC56G67CTCA99C + b[[WZ56W]87X9HBB @44FC6%%%%&&&&&&&1UP1 GTS4HY2IOMD3FCCA8DFLLLTG + ]]^4YY23ZV\6`a8`^9^a 等等 我希望我的输出看起来像: @F7##########0/1 C4CTA6GCAAC56G67CTCA99C +F7#

我尝试在以下输入上使用简单的perl one liner:

@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
等等

我希望我的输出看起来像:

@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a
等等

我想搜索以
@
开头的行,并将该行的其余部分存储(分组)在
$1
中。然后我找到下一个出现的
+
,并将
$1
添加到该行的末尾

我尝试了
perl-pi-e“s%^@(.*)$\1\n(.*)$\2\n(\+)$\3\n%$1\n$2\n\+$1%mg”file.txt
,但我似乎无法匹配
^@(.*)$\1\n
之后的任何内容


当然,有一个工作班轮在那里完成这一点
Awk
Sed
tr
一行程序是受欢迎的,但是对
file.txt
的更改必须在线进行,因为
file.txt
很大,不希望写入另一个文件。

下面的程序似乎可以满足您的需要

use strict;
use warnings;

my $str = <<'STR';
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
STR

$str =~ s/^@(.+?)$(.+?)^\+/\@$1$2+$1/gms;

print $str;

下面的程序似乎可以满足您的需要

use strict;
use warnings;

my $str = <<'STR';
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
STR

$str =~ s/^@(.+?)$(.+?)^\+/\@$1$2+$1/gms;

print $str;

不幸的是,
awk
不提供在线更改,因此它可能不是您所需要的。但是如果你这样做了,那么下面的方法就行了-

awk '/^@/{a=substr($0,2)}/^\+/{printf ("%s%s\n", $0,a);next}1' file > newfile
更新:我已尝试执行您在
sed
中希望执行的操作,该操作允许对文件中的
进行更改

sed -i '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
说明:
  • /^@/{h}
    :我们寻找以
    @
    符号开头的行,当我们找到它时,我们将整行放入
    保留空间中
    Sed
    有两个缓冲区,
    模式空间
    保持空间
    <代码>模式空间
    是所有操作发生的地方<代码>保留空间
允许我们暂时保留信息,以便稍后对其执行某些操作
  • /^\+/{x;…
    :当我们找到一行以
    +
    开头时,我们对它执行
    x
    操作。它的意思是,我们从
    保留空间中提取信息,然后将其放回
    模式空间中。一旦我们这样做了,我们就做了一个简单的替换
  • …s/\(.\)\(.*\)/+\2/
    :这意味着我们使用
    分组
    来识别字符。因为我们的文本部分前面有
    @
    ,这是您不想要的,所以我们使用
    来隔离该字符,这意味着任何字符。我们还将该行的所有其他内容放在第二个组中。这些组需要转义{所以你看到的是\(\)而不是()}。在替换部分,我们放入了一个
    +
    和第二个组。记住,捕获的第一个组中只有
    @
    。我们只需要第二个组,所以我们使用
    \2
    引用它(反斜杠和您希望引用的组数)
  • 测试
    awk
    : 测试
    sed
    : 您可以使用
    -i
    选项进行适当的更改。以下仅用于演示,以便您可以查看输出

    [jaypal:~/Temp] sed '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
    @F7##########0/1
    C4CTA6GCAAC56G67CTCA99C
    +F7##########0/1
    b[[WZ56W]87X9HBB
    @44FC6%%%%&&&&&&&1UP1
    GTS4HY2IOMD3FCCA8DFLLLTG
    +44FC6%%%%&&&&&&&1UP1
    ]]^4YY23ZV\6`a8`^9^a
    

    不幸的是,
    awk
    不提供在线更改,因此它可能不是您所需要的-

    awk '/^@/{a=substr($0,2)}/^\+/{printf ("%s%s\n", $0,a);next}1' file > newfile
    
    更新:我已尝试执行您在
    sed
    中希望执行的操作,该操作允许对文件中的
    进行更改

    sed -i '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
    
    说明:
    • /^@/{h}
      :我们寻找以
      @
      符号开头的行,当我们找到它时,我们将整行放入
      保留空间
      Sed
      有两个缓冲区,
      模式空间
      保留空间
      模式空间
      是所有操作发生的地方。
      保留空间
      允许我们保留信息暂时停止,以便我们以后可以对其采取一些行动
    • /^\+/{x;…
      :当我们找到一行以
      +
      开头时,我们对它执行
      x
      操作。它的意思是,我们从
      保留空间中提取信息,然后将其放回
      模式空间中。一旦我们这样做了,我们就做了一个简单的替换
    • …s/\(.\)\(.*\)/+\2/
      :这意味着我们使用
      分组
      来识别字符。因为我们的文本部分前面有
      @
      ,这是您不想要的,所以我们使用
      来隔离该字符,这意味着任何字符。我们还将该行的所有其他内容放在第二个组中。这些组需要转义{所以你看到的是\(\)而不是()}。在替换部分,我们放入了一个
      +
      和第二个组。记住,捕获的第一个组中只有
      @
      。我们只需要第二个组,所以我们使用
      \2
      引用它(反斜杠和您希望引用的组数)
    测试
    awk
    : 测试
    sed
    : 您可以使用
    -i
    选项进行适当的更改。以下仅用于演示,以便您可以查看输出

    [jaypal:~/Temp] sed '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
    @F7##########0/1
    C4CTA6GCAAC56G67CTCA99C
    +F7##########0/1
    b[[WZ56W]87X9HBB
    @44FC6%%%%&&&&&&&1UP1
    GTS4HY2IOMD3FCCA8DFLLLTG
    +44FC6%%%%&&&&&&&1UP1
    ]]^4YY23ZV\6`a8`^9^a
    

    我很抱歉。我更仔细地阅读了你的问题,发现你想一行一行地处理你的文件。这一行就可以做到这一点

    perl -pe "$dat = $1 if /^\@(.+)/; s/^\+/+$dat/;" infile
    

    我很抱歉。我更仔细地阅读了你的问题,发现你想一行一行地处理你的文件。这一行就可以做到这一点

    perl -pe "$dat = $1 if /^\@(.+)/; s/^\+/+$dat/;" infile
    

    这可能适合您:

    sed '/^@/h;/^+/{G;s/\n@//}' file
    @F7##########0/1
    C4CTA6GCAAC56G67CTCA99C
    +F7##########0/1
    b[[WZ56W]87X9HBB
    @44FC6%%%%&&&&&&&1UP1
    GTS4HY2IOMD3FCCA8DFLLLTG
    +44FC6%%%%&&&&&&&1UP1
    ]]^4YY23ZV\6`a8`^9^a
    

    这可能适合您:

    sed '/^@/h;/^+/{G;s/\n@//}' file
    @F7##########0/1
    C4CTA6GCAAC56G67CTCA99C
    +F7##########0/1
    b[[WZ56W]87X9HBB
    @44FC6%%%%&&&&&&&1UP1
    GTS4HY2IOMD3FCCA8DFLLLTG
    +44FC6%%%%&&&&&&&1UP1
    ]]^4YY23ZV\6`a8`^9^a
    

    当我尝试使用
    sed
    时,那行
    sed
    正是我最初想要的。然而,当我无法匹配或替换
    \n
    时,我放弃了
    sed
    。它看起来像复杂的正则表达式,你介意为我解释一下吗?那真的很好!一个A+解释。谢谢!做得好。在sed解决方案中在
    /^\+/
    上,我被抛出了一会儿,因为没有
    -r
    开关
    +
    不是特殊的,通常不需要转义。但是,如果转义,它意味着前面的字符或子表达式中有
    一个或多个
    ,但是在反常的逻辑中,
    ^
    是位置标记,而不是一个字符,它会还原为一个字符<