我有一个文件,其中包含由模式/#matchee/分隔的记录。这些记录的长度各不相同……例如 45 - 75 行。它们需要全部为 45 行,并且仍然保留记录分隔符。记录可以来自不同的部门,部门名称位于第 2 行空行之后。因此,记录分隔符可以简单地视为/^#matchee/或/^matchee/后跟\n。此问题有一个豪华版本和一个沃尔玛版本...
豪华版
按模式范围拉取每条记录,以便我可以按部门对记录进行排序。例如,使用 sed
sed -n '/^DEPARTMENT NAME/,/^#matchee/{p;}' mess-o-records.txt
然后,仅打印文件中每条记录的前 45 行,以符合 45 行约束。
最后,确保结果在第 45 行仍然具有记录分隔符。
沃尔玛版
与上面相同,但不使用范围,而是使用记录分隔符。
状态
我对此的尝试可能会澄清我正在尝试做的事情。
sed -n -e '/^DEPARTMENT-A/,/^#matchee/{p;}' -e '45q' -e '$s/.*/#matchee/' mess-o-records.txt
当然,这不起作用,因为 sed 在每个命令中都对整个文件进行操作。 我需要它对每个范围匹配进行操作而不是整个文件。
示例输入 - 80 行(因空格而被截断)
<blank line>
DEPARTMENT-A
Office space 206
Anonymous, MI 99999
Harold O Nonymous
Buckminster Abbey
Anonymous, MI 99999
item A Socket B 45454545
item B Gizmo Z 76767676
<too many lines here>
<way too many lines here>
#matchee
示例输出 - 现在只有 45 行
<blank line>
DEPARTMENT-A
Office space 206
Anonymous, MI 99999
Harold O Nonymous
Buckminster Abbey
Anonymous, MI 99999
item A Socket B 45454545
item B Gizmo Z 76767676
<Record now equals exactly 45 lines>
<yet record delimiter is maintained>
#matchee
澄清更新
如果这能让事情变得更容易,我永远不需要超过前 40 行。也许这个过程是:
- 匹配模式
- 打印前 40 行。
- 垫至适当的长度。例如,45 行。
- 重新添加分隔符。例如,#matchee
我认为这会更灵活——即,可以处理短于 45 行的记录。
下面是基于 @Borodin 的 Perl 示例的即兴演奏:
my $count = 0;
$/ = "#matchee";
while (<>) {
if (/^REDUNDANCY.*DEPT/) {
print;
$count = 0;
}
else {
print if $count++ < 40;
print "\r\n" x 5;
print "#matchee\r\n";
}
}
这会向每个记录添加 5 个换行符 + 分隔模式/#matchee/。所以这是错误的——但它说明了我想要的。
根据部门 -- pad -- 大头钉分隔符打印 40 行。
最佳答案
我想我明白你想要什么。不确定按模式范围提取每个记录。是#matchee
总是后面跟着一个空行,然后是部门行?那么事实上记录号是 2?
这个 Perl 片段可以满足我的需求。
如果您愿意,可以将输入文件放在命令行上并删除 open
称呼。那么循环必须是 while (<>) { ... }
.
请告诉我们到目前为止这是否正确,以及您还需要什么。
use strict;
use warnings;
open my $fh, '<', 'mess-o-records.txt' or die $!;
my $count = 0;
while (<$fh>) {
if (/^#matchee/) {
print;
$count = 0;
}
else {
print if $count++ < 45;
}
}
关于perl - sed、awk 或 perl : Pattern range match, 打印 45 行然后添加记录分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9843724/