我总是处理由以下格式的许多数据块组成的数据文件:
*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
)
无论如何,我可以从命令行中使用单行提取我感兴趣的“名称”吗?
答案 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)
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中实现。