2011-07-12 14 views
1

Unixでは、私がやりたいことは "history | grep keyword"です。多くのタイプのキーワードをgrepしたいのですが、ですから、私はそれを自動化したいのですが、キーワードを変更するだけでコマンドを繰り返すのではなく、すべてのことをするPerlスクリプトを書いていますので、それらのコマンドを見たいときはいつでもPerlスクリプトを使って私。Unixのコマンド "history | grep keyword"と同じように動作するPerlスクリプト

「grep」にしたいキーワードは、source、ls、cdなどです。 どのような方法であれ、どのような形式でも印刷できます。

ありがとうございます!コメントありがとうございます。

+2

なぜperlスクリプトを使用してunixコマンドを自動化するのですか?なぜシェルスクリプトではないのですか?単純なエイリアス。あなたが救うのはすべて "歴史| grep"と書いてありますので、私が見ているところでは、価値は限られています。 – TLP

答えて

2

history | grep whateverは清潔でシンプルでいいです...(@チャス・オーウェンズのおかげで)

#!/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"; 
     } 
} 

は正直にを修正しました。 )

ノートコードは、私はあなたがあなたの空想のマッチング(すなわち、grepのを置き換えます)行いますが履歴ファイルを読み取らないPerlスクリプトを書いたほうが良いと思います

+3

'open'の2つの引数バージョンは危険です。常に3つの引数バージョンを使用してください: 'my $ historyFile =" .bash_history ";私の$ fh、 "<"、$ historyFileまたはdie "$ historyFile:$!"を開くことができませんでした。; –

+0

歓声 - 更新 – sdolgy

0

完璧ではないかもしれません。これは、シェルを終了するまで、履歴が.bash_historyファイルにフラッシュされていないようだからです。これを制御する設定や環境変数があるかもしれませんが、私はそれらが何であるか分かりません。あなただけのお気に入りのコマンドのためにSTDINをscanns perlスクリプトを書くのであれば、あなたが

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"; 
    } 
} 
+0

ねえ、コメントありがとう。 "history | perl_script"の参照はありますか?私はこのスクリプトに何が含まれていなければならないかは分かりません。 – keifer

+0

@keiferサンプルperlスクリプトが追加されました。ちょうど引数ではなく、コマンドをチェックします。 – Sodved

0

これはPerlであり、これを行う方法はたくさんあります。最も簡単なのは、おそらくです:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

これは、シェルコマンドcat ~/.bash_historyを実行し、行のリストとして出力を返します。その後、行のリストはgrep関数によって消費されます。 grep関数は、すべての項目に対してコードブロックを実行し、真の戻り値を持つものだけを返します。したがって正規表現と一致する行だけを返します。

このコードはそれと間違っていくつかのものを持っている(それはcatを実行するためのシェルを起動します、それはなど、$regexは危険なものが含まれている可能性があり、メモリ内のファイル全体を保持している)が、安全な環境での速度/メモリISN」問題は、それはすべて悪いことではありません。

優れたスクリプトは、このスクリプトは、それが簡単にそれは後日、使用している歴史のファイルに変更できるようにすることconstantを使用しています

#!/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; 
} 

だろう。履歴ファイルを直接開き、1行ずつ読み込みます。つまり、ファイル全体が決してメモリに格納されません。ファイルが非常に大きい場合、これは非常に重要です。それでも、$regexには有害な正規表現が含まれているかもしれないという問題がありますが、あなたが実行している人ならば、あなた自身が責任を負うだけです(しかし、私は外部のユーザにこのようなコマンドウェブアプリケーション)。

+0

コメントありがとうございますが、私のホームディレクトリの履歴は、 ".bash_history"の代わりに ".history"ファイルに保存され、 ".history"ファイルは最新のコマンドを更新しませんxtermが閉じられるか、それを更新するために "history -S"とタイプする必要があります。 – keifer

+0

'history'はプログラムではなく、シェルの一部です。これは、Perlがまだメモリに残っているコンテンツに到達することはほぼ不可能であることを意味します。プログラムを実行して検索するパイピングは、あなたの唯一の答えです。これの簡単な例は 'history | perl -ne 'は/ \ b(?:ls | source | cd)\ b /' 'ならば印刷します。これは、ls、source、およびcdという単語に一致する行だけを出力します。 –

1

あなたはgrepの新しい十分なバージョンを持っている場合、私は、Perl互換正規表現ライブラリに切り替わりますキーワード

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

-Pのgrepの多くの種類をしたい場合、それは非常にいくつかの手順がかかるので。

関連する問題