在文本文件中获取已知模式之间的数据

时间:2015-03-12 21:53:09

标签: perl

以下是我想要处理的文本文件。

##BEGIN Text file
A . B.
DATA1
DATA12
DATA13
A  C
DATA2
DATA22
DATA23
A . B.
DATA3
DATA32
DATA33
A . B.
DATA4
DATA42
DATA43
A . B.
DATA5
DATA52
DATA53
A . B.
DATA6
DATA62
DATA63
## END text file

现在我想获得以下输出。

DATA1
DATA12
DATA13
DATA3
DATA32
DATA33
DATA4
DATA42
DATA43
DATA5
DATA52
DATA53
DATA6
DATA62
DATA63

我使用了以下perl命令行,但无法获得我需要的内容。你能否告诉我是否有办法在命令行中实现这一点。

perl -ne 'print if(/B/.../^A/)' ~/data | grep -v ^A

1 个答案:

答案 0 :(得分:0)

岂不:

perl -ne 'print if m/DATA/' ~/data

有想要的结果吗?

您尝试使用的范围运算符不能像您想象的那样工作,因为它可以捕获两种模式...但是这样做包含 - 但我也不确定它将如何处理开始和结束模式是同一条线。

快速测试:

#!/usr/bin/perl
use strict;
use warnings;

while ( <DATA> ) {
   print if ( /B/ ... /^A/ );
}

__DATA__
A B
1
2
3
A B
4
5
6
A B

给出:

A B
1
2
3
A B
A B

认为这意味着第一个模式是'匹配'但是第二个模式匹配没有检查该行的其余部分 - 它继续到下一行。

所以看看你的数据 - 你有一个标题行,你想要的数据是'A。 B'在顶部(和你没有'A C'的那个)。

所以我认为你可以设置$/来处理这个问题:   - $/是记录分隔符 - 通常这是\n所以换行,但如果我们将其设置为\nA,我们会抓取多行块。   - 然后我们测试B的存在(基于上面 - 你想要带有B的东西,但不是带有C的东西)。   - 然后我们应用几个正则表达式来删除A . B行。 (它有点混乱,因为它分成两个块)

#!/usr/bin/perl
use strict;
use warnings;

{
    local $/ = "\nA";
    while (<DATA>) {
        if ( m/B/ ) {
            s/\n^A$//gm;
            s/.*B\.$//gm;
            print;
        }
    }
}

__DATA__
A . B.
DATA1
DATA12
DATA13
A  C
DATA2
DATA22
DATA23
A . B.
DATA3
DATA32
DATA33
A . B.
DATA4
DATA42
DATA43
A . B.
DATA5
DATA52
DATA53
A . B.
DATA6
DATA62
DATA63

给出:

DATA1
DATA12
DATA13
DATA3
DATA32
DATA33
DATA4
DATA42
DATA43
DATA5
DATA52
DATA53
DATA6
DATA62
DATA63

我认为哪个应该做的?