一个衬垫逐块提取数据

时间:2009-04-02 08:10:21

标签: command-line text

我总是处理由以下格式的许多数据块组成的数据文件:

*name* attr (
        VALID (
                late_lead_up xxx ar uclk reff xxx slope xxx
                late_lead_dn xxx af uclk reff xxx slope xxx
                early_trail_up xxx af uclk reff xxx slope xxx
                early_trail_dn xxx ar uclk reff xxx slope xxx
              )
        CEXT xxx
        CREF xxx
        REFF xxx
        QUALIFIED_CLOCK
)

无论如何,我可以从命令行中使用单行提取我感兴趣的“名称”吗?

6 个答案:

答案 0 :(得分:1)

将此文件用于演示目的:

of_interest attr (
    1:VALID (
        1:late_lead_up xxx ar uclk reff xxx slope xxx
        1:late_lead_dn xxx af uclk reff xxx slope xxx
        1:early_trail_up xxx af uclk reff xxx slope xxx
        1:early_trail_dn xxx ar uclk reff xxx slope xxx
    1:)
    1:CEXT xxx
    1:CREF xxx
    1:REFF xxx
    1:QUALIFIED_CLOCK
)

boring attr (
    2:VALID (
        2:late_lead_up xxx ar uclk reff xxx slope xxx
        2:late_lead_dn xxx af uclk reff xxx slope xxx
        2:early_trail_up xxx af uclk reff xxx slope xxx
        2:early_trail_dn xxx ar uclk reff xxx slope xxx
    2:)
    2:CEXT xxx
    2:CREF xxx
    2:REFF xxx
    2:QUALIFIED_CLOCK
)

of_interest attr (
    3:VALID (
        3:late_lead_up xxx ar uclk reff xxx slope xxx
        3:late_lead_dn xxx af uclk reff xxx slope xxx
        3:early_trail_up xxx af uclk reff xxx slope xxx
        3:early_trail_dn xxx ar uclk reff xxx slope xxx
    3:)
    3:CEXT xxx
    3:CREF xxx
    3:REFF xxx
    3:QUALIFIED_CLOCK
)

这个单行(为便于阅读而分开):

awk '
    BEGIN               {s=0}
    /^of_interest /     {s=1}
    /^)$/               {if (s==1) {print};s=0}
                        {if (s==1) print}'

或最小字符版本:

awk 'BEGIN{s=0}/^of_interest /{s=1}/^)$/{if(s==1){print};s=0}{if(s==1)print}'

给你:

of_interest attr (
    1:VALID (
        1:late_lead_up xxx ar uclk reff xxx slope xxx
        1:late_lead_dn xxx af uclk reff xxx slope xxx
        1:early_trail_up xxx af uclk reff xxx slope xxx
        1:early_trail_dn xxx ar uclk reff xxx slope xxx
    1:)
    1:CEXT xxx
    1:CREF xxx
    1:REFF xxx
    1:QUALIFIED_CLOCK
)
of_interest attr (
    3:VALID (
        3:late_lead_up xxx ar uclk reff xxx slope xxx
        3:late_lead_dn xxx af uclk reff xxx slope xxx
        3:early_trail_up xxx af uclk reff xxx slope xxx
        3:early_trail_dn xxx ar uclk reff xxx slope xxx
    3:)
    3:CEXT xxx
    3:CREF xxx
    3:REFF xxx
    3:QUALIFIED_CLOCK
)

我相信你所追求的是什么。

它基本上是一个简单的状态机,当它找到所需的块启动时打开打印,并在找到该块的结束时将其关闭。

更新:这是一个perl one-liner,负责你的qualified_clock要求。享受: - )

perl -e '$s=1;while(<STDIN>){if(/^of_interest /){$s=1;$f=0;$x="";}if(($s==1)&&/QUALIFIED_CLOCK/){$f=1;}if(/^\)$/){if($s==1){$x.=$_;}if($f==1){print$x;}$s=0;next;}if($s==1){$x.=$_;}}'

答案 1 :(得分:1)

Pax's one

更少的字符和更简单的解决方案
perl -ne '/^of_interest /../^\)/ and print'

awk '/^of_interest /,/^\)/{print}'

sed -n '/^of_interest /,/^)/p'

答案 2 :(得分:0)

如果你的广告代码块始终以“*name* attr (”开头并且始终以“)”结尾,没有前导空格,则可以尝试(假设foo是块名称, data.txt是要解析的文件:

awk '/ attr \($/ {if($1==n)b=1}  {if(b)print}  /^\)$/ {b=0}' n=foo data.txt

答案 3 :(得分:0)

好吧,你把它标记为Perl,所以这就是我在Perl中的表现方式:

#!/usr/bin/perl

use strict;
use warnings;

die "usage: $0 name datafile\n    or cat datafile | $0 name\n" 
    unless @ARGV > 0;

my $name = shift;
my $re   = qr/\A$name attr/; 

my $rec = '';
while (my $line = <>) {
    $rec .= $line;
    next unless $line =~ /^\)/;
    print $rec if $rec =~ /$re/;
    $rec = '';
}

你可以把它变成像这样的单行

perl -ne '$a.=$_;next unless/^\)/;print$a if$a=~/^name/;$a=""' datafile

但我更喜欢这个剧本。请记住将name替换为记录名称。

答案 4 :(得分:-1)

以下是Perl单行的一种方法:

perl -ne '$m = 1 if /^insert_name_here attr/; print if $m; $m = 0 if /^\)$/' file.txt

答案 5 :(得分:-1)

我在你的评论中看到另一个答案,你也想在块中搜索像'QUALIFIED_CLOCK'这样的字符串。

在这种情况下,如果您的数据块用空行分隔,您可以使用Perl的段落模式以块的形式读取它并打印出您感兴趣的那些。例如:

perl -00 -ne 'print if /^block_name/ and /QUALIFIED_CLOCK/' file.txt

通过设置RS,这也可以在awk中实现。