perl - sed、awk 或 perl : Pattern range match, 打印 45 行然后添加记录分隔符

标签 perl sed awk

我有一个文件,其中包含由模式/#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/

相关文章:

Perl read_config sub,oop 与否?

linux - 未终止的正则表达式 Linux

bash - 如何grep文件中不区分大小写的字符串?

bash - 在第二个模式 sed 之后删除行

.csv 格式的正则表达式和定位项

awk - 记录不分界时将多行记录创建为单行

bash - 如何在行尾附加模式匹配数的计数器?

perl - perl中\0是什么意思?

javascript - 如何解码 JSON 字符串?

windows - Perl 包问题