Command line 一个用于逐块提取数据的线性函数
我总是处理由以下格式的许多数据块组成的数据文件:Command line 一个用于逐块提取数据的线性函数,command-line,text,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
*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
)
还有什么方法可以从命令行中提取我感兴趣的“名称”吗?如果您的块总是以“
*name*attr(
”开头,并且总是以“)
”结尾,没有前导空格,您可以尝试(假定foo
是块名,data.txt
是要解析的文件):
好的,您将其标记为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 = '';
}
但我更喜欢剧本。记住用记录的名称替换名称。出于演示目的使用此文件:
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}'
给你:
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,它可以满足您的合格时钟需求。享受:-)
perl-e'$s=1;while(){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)}
以下是一种将其作为Perl单行程序的方法:
perl -ne '$m = 1 if /^insert_name_here attr/; print if $m; $m = 0 if /^\)$/' file.txt
我在您对另一个答案的评论中看到,您还希望在块中搜索类似“QUALIFIED_CLOCK”的字符串 在这种情况下,如果您的数据块由一个空行分隔,则可以使用Perl的段落模式以块的形式读取数据块,并打印出您感兴趣的数据块。例如:
perl -00 -ne 'print if /^block_name/ and /QUALIFIED_CLOCK/' file.txt
这在awk中也可以通过设置RS来实现。比 或 或
你知道该块有多少行吗?行号不固定。行名和右括号出现在行首?行的开头是否还显示了其他内容?没有名称和右括号。请参阅我的更新,了解考虑了“限定时钟”要求的perl解决方案-不是最可读的一行,尽管它可以转换为脚本。如果某些数据块具有限定时钟,而某些数据块没有,我想用合格的时钟提取所有块?然后你需要存储行而不是打印它们,启动块时清除标志,如果找到合格的时钟则设置它,当找到块结束时,如果设置标志则输出所有行。如果有更多的要求更改,我会选择使用基于Python/Perl的解决方案,但它在任何语言中都不是一个可读的单行程序:-)
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 -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.=$_;}}'
perl -ne '$m = 1 if /^insert_name_here attr/; print if $m; $m = 0 if /^\)$/' file.txt
perl -00 -ne 'print if /^block_name/ and /QUALIFIED_CLOCK/' file.txt
perl -ne '/^of_interest /../^\)/ and print'
awk '/^of_interest /,/^\)/{print}'
sed -n '/^of_interest /,/^)/p'