如何使用Perl 6从嘈杂文件的中间提取一些数据?

Chr*_*oms 2 parsing text perl6 flip-flop raku

我想用惯用的Perl 6来做这件事.

我在一个嘈杂的输出文件中找到了一个很棒的连续数据块.

我想简单地打印出标题行,从Cluster Unique它后面的所有行开始,直到但不包括第一次出现空行.这是文件的样子:

</path/to/projects/projectname/ParameterSweep/1000.1.7.dir> was used as the working directory.
....

Cluster Unique Sequences    Reads   RPM
1   31  3539    3539
2   25  2797    2797
3   17  1679    1679
4   21  1636    1636
5   14  1568    1568
6   13  1548    1548
7   7   1439    1439

Input file: "../../filename.count.fa"
...
Run Code Online (Sandbox Code Playgroud)

这是我要解析的内容:

Cluster Unique Sequences    Reads   RPM
1   31  3539    3539
2   25  2797    2797
3   17  1679    1679
4   21  1636    1636
5   14  1568    1568
6   13  1548    1548
7   7   1439    1439
Run Code Online (Sandbox Code Playgroud)

Chr*_*oms 6

单线版

.say if /Cluster \s+ Unique/ ff^ /^\s*$/ for lines;
Run Code Online (Sandbox Code Playgroud)

用英语讲

打印输入文件中的每一行,从包含短语的一次开始,Cluster Unique到下一个空行之前结束.

带注释的相同代码

.say                    # print the default variable $_
if                      # do the previous action (.say) "if" the following term is true
/Cluster \s+ Unique/    # Match $_ if it contains "Cluster Unique"
ff^                     # Flip-flop operator: true until preceding term becomes true
                        #                     false once the term after it becomes true
/^\s*$/                 # Match $_ if it contains an empty line
for                     # Create a loop placing each element of the following list into $_
lines                   # Create a list of all of the lines in the file
;                       # End of statement
Run Code Online (Sandbox Code Playgroud)

扩展版

for lines() {
    .say if (
        $_ ~~ /Cluster \s+ Unique/  ff^  $_ ~~ /^\s*$/
    )
}
Run Code Online (Sandbox Code Playgroud)
  • lines()就像<>perl5.命令行中列出的每个文件的每一行都一次读取一行.由于这是一个for循环,每一行都放在默认变量中$_.
  • say就像打印一样,除了它还附加换行符.使用start开头时.,它直接作用于默认变量$_.
  • $_ 是默认变量,在这种情况下包含文件中的一行.
  • ~~$_与正则表达式进行比较的匹配运算符.
  • // 在两个正斜杠之间创建正则表达式
  • \s+ 匹配一个或多个空格
  • ff触发器操作员.只要左边的表达式为假,它就是假的.当左边的表达式被评估为真时,它变为真.当右边的表达式变为真,并且永远不再被评估为真时,它变为错误.在这种情况下,如果我们使用^ff^而不是ff^,那么标题将不会包含在输出中.
  • ^它来到之前(或之后)时ff,它会进行修改ff,以使其左侧(或右侧)表达式变为真的迭代也为假.
  • /^\*$/ 匹配一个空行
    • ^ 匹配字符串的开头
    • \s* 匹配零个或多个空格
    • $ 匹配字符串的结尾

顺便说一下,Perl 5中的触发器操作符是..它在标量上下文中(它是列表上下文中的范围操作符).但它的功能并不像Perl 6那样丰富,当然.