与unix命令“history | grep keyword”相同的Perl脚本

时间:2011-07-12 07:04:12

标签: perl unix

在Unix中,我想要做的是“历史| grep关键字”,只是因为如果我想要grep许多类型的关键字需要相当多的步骤,所以我希望它是自动化,我写了一个Perl脚本做所有事情,而不是仅仅通过更改关键字来重复命令,所以每当我想看到那些特定命令时,我都会使用Perl脚本为我做。

我想'grep'的关键字是source,ls,cd等。 它可以以任何格式打印出来,只要知道如何操作即可。

谢谢!我感谢任何评论。

4 个答案:

答案 0 :(得分:2)

已修改(感谢@ chas-owens)

 #!/bin/perl
 my $searchString = $ARGV[0];
 my $historyFile = ".bash.history";
 open FILE, "<", $historyFile or die "could not open $historyFile: $!";
 my @line = <FILE>;
 print "Lines that matched $searchString\n";
 for (@lines) {
      if ($_ =~ /$searchString/) {
           print "$_\n";
      }
 }

<强>原始

 #!/bin/perl
 my $searchString = $ARGV[0];
 my $historyFile = "<.bash.history";
 open FILE, $historyFile;
 my @line = <FILE>;
 print "Lines that matched $searchString\n";
 for (@lines) {
      if ($_ =~ /$searchString/) {
           print "$_\n";
      }
 }
老实说...... history | grep whatever简洁明快; )

注意代码可能不完美

答案 1 :(得分:1)

  

因为如果我想要使用多种类型的关键字,需要花费很多步骤

history | grep -E 'ls|cd|source'
如果你有足够新的grep版本,

-P将打开Perl兼容的正则表达式库。

答案 2 :(得分:0)

我认为你最好写一个你喜欢匹配的perlscript(即替换grep),但不会读取历史文件。我这样说是因为在退出shell之前,历史记录似乎没有刷新到.bash_history文件。现在可能有设置和/或环境变量来控制它,但我不知道它们是什么。因此,如果您只编写一个perl脚本来扫描STDIN以获取您喜欢的命令,则可以像

一样调用它
history | findcommands.pl

如果您在设置shell函数或别名之后输入的次数较少,则为您执行此操作。

根据@keifer的要求,这是一个示例perl脚本,用于搜索历史记录中的指定(或默认命令集)。很糟糕的是,您应该将dflt_cmds更改为您最常搜索的那些。

#!/usr/bin/perl
my @dflt_cmds = qw( cd ls echo );
my $cmds = \@ARGV;
if( !scalar(@$cmds) )
{
    $cmds = \@dflt_cmds;
}
while( my $line = <STDIN> )
{
    my( $num, $cmd, @args ) = split( ' ', $line );
    if( grep( $cmd eq $_ , @$cmds ) )
    {
        print join( ' ', $cmd, @args )."\n";
    }
}

答案 3 :(得分:0)

这是Perl,有很多方法可以做到。最简单的可能是:

#!/usr/bin/perl

use strict;
use warnings;

my $regex = shift;
print grep { /$regex/ } `cat ~/.bash_history`;

这将运行shell命令cat ~/.bash_history并将输出作为行列表返回。然后grep函数使用行列表。 grep函数为每个项运行代码块,只返回具有真实返回值的代码块,因此它只返回与正则表达式匹配的行。

这段代码有几个问题(它产生一个shell来运行cat,它将整个文件保存在内存中,$regex可能包含危险的东西等),但是在一个安全的速度/记忆不是问题的环境,并不是那么糟糕。

更好的脚本是

#!/usr/bin/perl

use strict;
use warnings;

use constant HISTORYFILE => "$ENV{HOME}/.bash_history";

my $regex = shift;

open my $fh, "<", HISTORYFILE
    or die "could not open ", HISTORYFILE, ": $!";

while (<$fh>) {
    next unless /$regex/;
    print;
}

此脚本使用constant可以更轻松地更改后期使用的历史文件。它直接打开历史文件并逐行读取。这意味着整个文件永远不会在内存中。如果文件非常大,这可能非常重要。它仍然存在$regex可能包含有害正则表达式的问题,但只要您是运行它的人,您只能责怪自己(但我不会让外部用户将参数传递给像这样的命令通过,说一个网络应用程序)。