![显示出现次数并计算它们之间以及最后一个之后的行数](https://linux22.com/image/230790/%E6%98%BE%E7%A4%BA%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%E5%B9%B6%E8%AE%A1%E7%AE%97%E5%AE%83%E4%BB%AC%E4%B9%8B%E9%97%B4%E4%BB%A5%E5%8F%8A%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%B9%8B%E5%90%8E%E7%9A%84%E8%A1%8C%E6%95%B0.png)
我有这个文件:
table_01 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_02 (id, field01, field02, field03)
record_01
table_03 (id, field01, field02, field03, field04)
record_01
record_02
table_04 (id, field01, field02, field03, field04, field04)
record_01
table_05 (id, field01, field02, field03, field04)
record_01
record_02
record_03
record_04
我想要一个脚本来显示出现单词“ table
”的行,并显示它们之间的行数以及最后一次出现之后的行数。
所以输出将是:
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
到目前为止我有这个脚本:
awk '$0 ~ /table/ {if (n) print NR-1-n; n=NR}' file
其输出为:
3
1
2
1
但该脚本不显示出现“ table
”的行,也不显示最后一次出现之后的行。我该如何修改它以显示缺少的内容?
答案1
显然,你已经完成了 90% 的任务:
awk '/table/ {if (n) 打印 NR-1-n; n=NR;打印} END {if (n) 打印 NR-1-n}' 文件
你不需要$0 ~
;这是暗示的。
答案2
我整理了一个 Perl 解决方案:
perl -Mfeature=say -e '
while (<>) {
if (/^table/) {
$c && say $c;
print;
$c = 0;
next;
}
$c++;
}
say $c;
' <input
user@server ~/[REDACTED] (git)-[REDACTED] % perl -Mfeature=say -e '
while (<>) {
if (/^table/) {
$c && say $c;
print;
$c = 0;
next;
}
$c++;
}
say $c;
' <input
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
答案3
我的答案假设一个场景,其中可以有空表(“空表”行/匹配行),以及一个通用场景,其中可能有额外的(非表/不匹配)行添加到输入文件中。
在这种情况下,要显示表行(匹配行)并计算其后续记录行(非匹配行)的出现次数,请使用awk
,如果需要模式为^table
:
awk '
/^$/ {next}
/^table/ {
if (precedingmatch)
{print 0}
else if (n)
{print n}
print; n=0; precedingmatch=1; matchesfound=1
}
!/^table/ {
if (matchesfound) {n++}
precedingmatch=0
}
END {if (matchesfound) {print n} else {print 0} }
' file.txt
precedingmatch
0
用于当后续两行是表格行时进行打印。matchesfound
用于忽略打印在任何第一个表行之前找到的非表行的计数。
file.txt
使用一些“空表”、换行符和一些随机前置的行进行示例:
randomline_01
randomline_02
table_01 (id, field01, field02, field03, field04)
table_02 (id, field01, field02, field03)
record_01
record_02
table_03 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_04 (id, field01, field02, field03, field04, field05)
table_05 (id, field01, field02, field03, field04)
输出:
table_01 (id, field01, field02, field03, field04)
0
table_02 (id, field01, field02, field03)
2
table_03 (id, field01, field02, field03, field04)
3
table_04 (id, field01, field02, field03, field04, field05)
0
table_05 (id, field01, field02, field03, field04)
0
没有“表”行的文件、空文件或充满换行符输出的文件0
。
答案4
使用乐(以前称为 Perl_6)
~$ raku -ne 'BEGIN my $c = 0; if /^table/ { $c && put $c; .put; $c = 0; next}; $c++;' file
Raku 是 Perl 系列中的一种编程语言,具有对 Unicode 的高级支持。这个 Raku 解决方案遵循 @kos 和 @terdon 发布的总体大纲(Perl 语言)。
示例输入(table
末尾有额外的行,尽管OP说这些不会遇到):
table_01 (id, field01, field02, field03, field04)
record_01
record_02
record_03
table_02 (id, field01, field02, field03)
record_01
table_03 (id, field01, field02, field03, field04)
record_01
record_02
table_04 (id, field01, field02, field03, field04, field04)
record_01
table_05 (id, field01, field02, field03, field04)
record_01
record_02
record_03
record_04
table_06 (id, field01, field02, field03, field04)
table_07 (id, field01, field02, field03, field04)
示例输出:
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
table_06 (id, field01, field02, field03, field04)
table_07 (id, field01, field02, field03, field04)
上面给出的答案与 @kos 和 @terdon 的 Perl 答案相同。更明确地说,块内的第一条语句可以写成$c.Bool && put $c;
或$c.so && put $c;
,但上面的代码就足够了。
如果没有插入“非表”记录,则插入零:
0
这是当record
标题后面没有行时返回的代码table
(类似于@Aeronautix 的答案):
~$ raku -ne 'BEGIN my $c = 0; if /^table/ { $c && put($c-1); .put; $c = 0}; $c++; END put($c-1);' file
table_01 (id, field01, field02, field03, field04)
3
table_02 (id, field01, field02, field03)
1
table_03 (id, field01, field02, field03, field04)
2
table_04 (id, field01, field02, field03, field04, field04)
1
table_05 (id, field01, field02, field03, field04)
4
table_06 (id, field01, field02, field03, field04)
0
table_07 (id, field01, field02, field03, field04)
0
注意:对于上面的所有答案,代码假设第一行以 开头table
,并且 OP 确认在第一行之前不会出现杂散行table
。
但是(对于其他用户/数据源),如果record
在文件顶部遇到杂散行,第一个答案将返回该杂散行之前的行数第一的表线。第二个答案将返回“一减”之前的行数第一的表线。