マッチした行からひとつふたつ離れた行を表示したかったので作ってみた Perl スクリプト。

使い方

Usage: zgrep ZURE PATTERN [files...]

ZURE パラメータ

出力したい行がマッチした行から何行離れているか指定する。
マッチした行をそのまま出力する場合は 0 を指定する。
マッチした行より前の行の場合は負の数を指定する。
マッチした行より後の行の場合は正の数を指定する。

PATTERN パラメータ

検索キーワードを指定する。
たとえば、「猫の手」を検索する場合は「猫の手」と指定する。
たとえば、「猫」で始まる行を検索する場合は「"^猫の手"」と指定する。

files パラメータ

検索対象のファイル名を記述する。ズラズラと並べて複数指定可能。

Windows での実行例

a.txt から「猫の手」を検索し、マッチした行の次の行を出力する

C:\>perl zgrep 1 猫の手 a.txt

ソースコード


# zgrep - zure grep
use strict;
 
# 参考: プログラミングPerl改訂版 2.7 サブルーチン(136ページ)
sub zuregrep{
  my $zure    = shift;
  my $coderef = shift;
  my @line    = @_;
  my @result;
  my $i;
  for ($i = 0; $i < @line; $i++){
    if ($line[$i] =~ /$coderef/){
      if($i + $zure < 0 || $i + $zure > $#line){
        push(@result, "\n"); # out of bounds
      }else{
        push(@result, $line[$i + $zure]);
      }
    }
  }
  @result;
}
 
if(@ARGV < 2){
  print STDERR 'Usage: zgrep ZURE PATTERN [files...]';
  exit;
}
 
# get parameters
my $zure    = shift @ARGV;
my $pattern = shift @ARGV;
my @files   = @ARGV;
 
# print parameters
print STDERR "PATTERN: $pattern\n";
print STDERR "FILES: ";
for(@files){
  print STDERR $_ . ' ';
}
print "\n";
 
# zure grep
for(@files){
  open FH, "< $_";
  my @line = <FH>;
  close FH;
  my @result = &zuregrep($zure, $pattern, @line);
  for(@result){
    print $_;
  }
}

tags: zlashdot Perl Perl

Posted by NI-Lab. (@nilab)