Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux aix/ksh shell中前后的grep行_Linux_Shell_Unix_Ksh_Aix - Fatal编程技术网

Linux aix/ksh shell中前后的grep行

Linux aix/ksh shell中前后的grep行,linux,shell,unix,ksh,aix,Linux,Shell,Unix,Ksh,Aix,我想提取匹配模式前后的线条 如果文件内容如下所示 absbasdakjkglksagjgj sajlkgsgjlskjlasj hello lkgjkdsfjlkjsgklks klgdsgklsdgkldskgdsg 我需要查找hello并在“hello”前后显示行 输出应该是 sajlkgsgjlskjlasj hello lkgjkdsfjlkjsgklks 这在GNU中是可能的,但我需要一种在AIX/KSH SHELL中工作的方法,在AIX/KSH SHELL中没有安装GNU。我发现

我想提取匹配模式前后的线条

如果文件内容如下所示

absbasdakjkglksagjgj
sajlkgsgjlskjlasj
hello
lkgjkdsfjlkjsgklks
klgdsgklsdgkldskgdsg
我需要查找hello并在“hello”前后显示行

输出应该是

sajlkgsgjlskjlasj
hello
lkgjkdsfjlkjsgklks

这在GNU中是可能的,但我需要一种在AIX/KSH SHELL中工作的方法,在AIX/KSH SHELL中没有安装GNU。

我发现,一次构建GNU coreutils通常不那么令人沮丧,并且受益于更多的特性

因为机器上有Perl,所以可以使用以下代码,但是安装GNU实用程序可能会更好。对于匹配之前的行,这有选项
-bn1
,对于匹配之后的行,有选项
-fn1
。它适用于PCRE匹配(因此,如果您想要不区分大小写的匹配,请在正则表达式之后添加一个
i
,而不是使用
-i
选项。我没有实现
-v
-l
;我不需要这些

sed -n '/hello/{x;G;N;p;};h' filename
#!/usr/bin/env perl
#
# @(#)$Id: sgrep.pl,v 1.7 2013/01/28 02:07:18 jleffler Exp $
#
# Perl-based SGREP (special grep) command
# 
# Print lines around the line that matches (by default, 3 before and 3 after).
# By default, include file names if more than one file to search.
#
# Options:
# -b n1     Print n1 lines before match
# -f n2     Print n2 lines following match
# -n        Print line numbers
# -h        Do not print file names
# -H        Do     print file names

use warnings;
use strict;
use constant debug => 0;
use Getopt::Std;
my(%opts);

sub usage
{
    print STDERR "Usage: $0 [-hnH] [-b n1] [-f n2] pattern [file ...]\n";
    exit 1;
}

usage unless getopts('hnf:b:H', \%opts);
usage unless @ARGV >= 1;

if ($opts{h} && $opts{H})
{
    print STDERR "$0: mutually exclusive options -h and -H specified\n";
    exit 1;
}

my $op = shift;

print "# regex = $op\n" if debug;

# print file names if -h omitted and more than one argument
$opts{F} = (defined $opts{H} || (!defined $opts{h} and scalar @ARGV > 1)) ? 1 : 0;
$opts{n} = 0 unless defined $opts{n};

my $before = (defined $opts{b}) ? $opts{b} + 0 : 3;
my $after  = (defined $opts{f}) ? $opts{f} + 0 : 3;

print "# before = $before; after = $after\n" if debug;

my @lines = (); # Accumulated lines
my $tail  = 0;  # Line number of last line in list
my $tbp_1 = 0;  # First line to be printed
my $tbp_2 = 0;  # Last line to be printed

# Print lines from @lines in the range $tbp_1 .. $tbp_2,
# leaving $leave lines in the array for future use.
sub print_leaving
{
    my ($leave) = @_;
    while (scalar(@lines) > $leave)
    {
        my $line = shift @lines;
        my $curr = $tail - scalar(@lines);
        if ($tbp_1 <= $curr && $curr <= $tbp_2)
        {
            print "$ARGV:" if $opts{F};
            print "$curr:" if $opts{n};
            print $line;
        }
    }
}

# General logic:
# Accumulate each line at end of @lines.
# ** If current line matches, record range that needs printing
# ** When the line array contains enough lines, pop line off front and,
#    if it needs printing, print it.
# At end of file, empty line array, printing requisite accumulated lines.

while (<>)
{
    # Add this line to the accumulated lines
    push @lines, $_;
    $tail = $.;

    printf "# array: N = %d, last = $tail: %s", scalar(@lines), $_ if debug > 1;

    if (m/$op/o)
    {
        # This line matches - set range to be printed
        my $lo = $. - $before;
        $tbp_1 = $lo if ($lo > $tbp_2);
        $tbp_2 = $. + $after;
        print "# $. MATCH: print range $tbp_1 .. $tbp_2\n" if debug;
    }

    # Print out any accumulated lines that need printing
    # Leave $before lines in array.
    print_leaving($before);
}
continue
{
    if (eof)
    {
        # Print out any accumulated lines that need printing
        print_leaving(0);
        # Reset for next file
        close ARGV;
        $tbp_1 = 0;
        $tbp_2 = 0;
        $tail  = 0;
        @lines = ();
    }
}
!/usr/bin/env perl
#
#@(#)$Id:sgrep.pl,v1.7 2013/01/28 02:07:18 jleffler Exp$
#
#基于Perl的SGREP(特殊grep)命令
# 
#围绕匹配的行打印行(默认情况下,前3行,后3行)。
#默认情况下,如果要搜索多个文件,则包括文件名。
#
#选项:
#-b n1在匹配前打印n1行
#-f n2在匹配后打印n2行
#-n打印行号
#-h不打印文件名
#-H不打印文件名
使用警告;
严格使用;
使用常量debug=>0;
使用Getopt::Std;
我的(%opts);
次级用途
{
打印标准“用法:$0[-hnH][-b n1][-f n2]模式[文件…]\n”;
出口1;
}
用法,除非getopts('hnf:b:H',\%opts);
用法,除非@ARGV>=1;
if($opts{h}&&$opts{h})
{
打印标准“$0:互斥选项-h和-h已指定\n”;
出口1;
}
我的$op=班次;
如果调试,则打印“#regex=$op\n”;
#如果省略了-h和多个参数,则打印文件名
$opts{F}=(定义的$opts{H}| |(!定义的$opts{H}和标量@ARGV>1))?1:0;
$opts{n}=0,除非定义了$opts{n};
my$before=(定义为$opts{b})$opts{b}+0:3;
my$after=(定义为$opts{f})$opts{f}+0:3;
如果调试,则打印“#before=$before;after=$after\n”;
我的@lines=();#累计行数
my$tail=0;#列表中最后一行的行号
my$tbp_1=0;#要打印的第一行
我的$tbp_2=0;#要打印的最后一行
#打印范围为$tbp_1..$tbp_2的@行中的行,
#在数组中保留$leave行以备将来使用。
子打印离开
{
我的($假期)=@;
while(标量(@行)>$leave)
{
我的$line=shift@line;
my$curr=$tail-scalar(@lines);
如果($tbp_1$tbp_2);
$tbp_2=$.+$之后;
如果调试,则打印“#$.MATCH:打印范围$tbp_1..$tbp_2\n”;
}
#打印出任何需要打印的累积行
#在数组中的行之前保留$。
打印离开($之前);
}
持续
{
如果(eof)
{
#打印出任何需要打印的累积行
打印(0);
#为下一个文件重置
关闭ARGV;
$tbp_1=0;
$tbp_2=0;
$tail=0;
@行=();
}
}

我遇到过这样一种情况:我在平板电脑上遇到了一个很慢的telnet会话,信不信由你,我无法用这个键盘很容易地编写Perl脚本。我想出了这个技巧,在AIX有限的grep环境下,它在紧要关头发挥了作用。如果你的grep返回数百行代码,这将无法很好地工作,但如果你只需要一行代码,我就可以使用它在它上面/下面有一个或两个,这样就可以了。首先我运行了这个:

cat-n文件名| grep标准

通过包含
-n
标志,我可以看到我正在查找的数据的行号,如下所示:

2543 my crucial data
由于
cat
在行号前2个空格和行号后1个空格处给出行号,因此我可以按如下方式在行号前grep:

2543 my crucial data
cat-n文件名| grep“2542”


我运行了几次,给了我第2542行和第2544行,结束了第2543行。就像我说的,这肯定是错误的,就像如果你有大量的数据可能有“2542”到处都是,但仅仅是简单地说几句,它工作得很好。

您不能使用
-a
-B
-C
选项吗?它在AIX SHELL上不工作。GNU没有安装。(KSH SHELL)