Скрипт Perl, который работает так же, как и Unix-команда «history | grep keyword» - PullRequest
1 голос
/ 12 июля 2011

в Unix, что я хочу сделать, это «history | grep keyword», просто потому, что требуется довольно много шагов, если я хочу grep многих типов ключевых слов, поэтому я хочу, чтобы это была автоматизация, для которой я пишу Perl-скриптделайте все, вместо того, чтобы повторять команды, просто меняя ключевое слово, поэтому всякий раз, когда я хочу увидеть эти определенные команды, я просто использую сценарий Perl, чтобы сделать это для меня.

Ключевое слово, которое я хотел бы'grep' - это source, ls, cd и т. д. Он может быть распечатан в любом формате, если только вы знаете, как это сделать.

Спасибо!Я ценю любые комментарии.

Ответы [ 4 ]

2 голосов
/ 12 июля 2011

изменено (спасибо @ 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 голос
/ 12 июля 2011

потому что, если я хочу grep многих типов ключевых слов, потребуется довольно много шагов

history | grep -E 'ls|cd|source'

-P включит Perl-совместимую библиотеку регулярных выражений, если у вас есть новыйдостаточно версии grep.

0 голосов
/ 12 июля 2011

Это Perl, есть много способов сделать это.Вероятно, самое простое:

#!/usr/bin/perl

use strict;
use warnings;

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

. При этом запускается команда оболочки cat ~/.bash_history, которая возвращает вывод в виде списка строк.Список строк затем используется функцией grep.Функция grep запускает блок кода для каждого элемента и возвращает только те из них, которые имеют истинное возвращаемое значение, поэтому она будет возвращать только те строки, которые соответствуют регулярному выражению.

Этот код имеет несколько ошибок в этом (он запускает оболочку для запуска 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 может содержать вредоносное регулярное выражение, но до тех пор, пока вы выполняете его, вы сами виноваты (но я бы не позволил внешним пользователям передавать аргументы такой команде, как эта,скажем, веб-приложение).

0 голосов
/ 12 июля 2011

Я думаю, что вам лучше написать perlscript, который вы хотите сопоставить (т.е. заменяет grep), но не читает файл истории. Я говорю это, потому что история, кажется, не сбрасывается в файл .bash_history, пока я не выйду из оболочки. Сейчас, вероятно, есть настройки и / или переменные окружения, чтобы контролировать это, но я не знаю, что это такое. Так что, если вы просто напишите Perl-скрипт, который сканирует STDIN для ваших любимых команд, вы можете вызвать его как

history | findcommands.pl

Если вы набрали меньше текста, вы настроили функцию оболочки или псевдоним, чтобы сделать это за вас.

В соответствии с запросом @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";
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...