2010-04-22 62 views
4

我想編寫一些小腳本,它們在命令行上具有增量搜索功能(「儘可能找你」)。如何在命令行上實現增量式查找(find-as-you-type)搜索?

使用案例:我的手機通過USB連接,使用gammu --sendsms TEXT我可以寫短信。我把電話簿設置爲CSV,並且希望以此爲基礎進行搜索。

什麼是最簡單/最好的方法來做到這一點?它可能在bash/zsh/Perl/Python或任何其他腳本語言中。

編輯: 解決方案:修改Term::Complete做了我想要的。請參閱下面的答案。

回答

4

繼Aiden Bell的提示之後,我嘗試了Perl中的Readline。 解決方案1使用期限::完成(也被CPAN,我認爲):

use Term::Complete; 
my $F; 
open($F,"<","bin/phonebook.csv"); 
my @terms = <$F>; chomp(@terms); 
close($F); 


my $input; 
while (!defined $input) { 
    $input = Complete("Enter a name or number: ",@terms); 
    my ($name,$number) = split(/\t/,$input); 
    print("Sending SMS to $name ($number).\n"); 
    system("sudo gammu --sendsms TEXT $number"); 
} 

按\完成,按Ctrl-d,看所有的可能性。

解決方案2:CTRL-d是一個擊鍵得多,因此,使用標準的期限::的Readline允許完成,僅使用顯示關閉可能的完成\。

use Term::ReadLine; 

my $F; 
open($F,"<","bin/phonebook.csv"); 
my @terms = <$F>; chomp(@terms); 
close($F); 

my $term = new Term::ReadLine; 
$term->Attribs->{completion_function} = sub { return @terms; }; 

my $prompt = "Enter name or number >> "; 

my $OUT = $term->OUT || \*STDOUT; 
while (defined (my $input = $term->readline($prompt))) { 
    my ($name,$number) = split(/\t/,$input); 
    print("Sending SMS to $name ($number).\n"); 
    system("sudo gammu --sendsms TEXT $number"); 
} 

該解決方案仍需要完成。

編輯:最終解決 修改期限::完成(http://search.cpan.org/~jesse/perl-5.12.0/lib/Term/Complete.pm)不給我上飛完成。

源代碼:http://search.cpan.org/CPAN/authors/id/J/JE/JESSE/perl-5.12.0.tar.gz 解決方案編號1與此修改一起使用。我會把整個樣本在線別的地方,如果這可以被某人使用

Completion.pm(只重用它是控制-d和\每個字符碼)的修改:

170c172,189

 my $redo=0; 

       @match = grep(/^\Q$return/, @cmp_lst); 
       unless ($#match < 0) { 
        $l = length($test = shift(@match)); 
        foreach $cmp (@match) { 
         until (substr($cmp, 0, $l) eq substr($test, 0, $l)) { 
          $l--; 
         } 
        } 
        print("\a"); 
        print($test = substr($test, $r, $l - $r)); 
          $redo = $l - $r == 0; 
          if ($redo) { print(join("\r\n", '', grep(/^\Q$return/, @cmp_lst)), "\r\n"); } 
        $r = length($return .= $test); 
       } 
        if ($redo) { redo LOOP; } else { last CASE; } 

+0

我認爲你會很難按下,除非你可以鉤住所有的按鍵。這些東西需要一個觸發器來調用完整的過程。 – 2010-04-22 13:20:21

+0

+1漂亮的小黑客。 – 2010-04-22 18:35:26

4

我得到的印象GNU Readline支持這種事情。雖然,我自己也沒有用過。自定義自動完成的Here is a C++ example,這也可以在C中輕鬆完成。 readline還有一個Python API

This StackOverflow question給出的例子在Python,其中一個是...

import readline 
def completer(text, state): 
    options = [x in addrs where x.startswith(text)] 
    if state < options.length: 
     return options[state] 
    else 
     return None 
readline.set_completer(completer) 

this article上猛砸自動完成功能可幫助。本文還給出了編程bash的自動完成功能的示例。

+1

使用bash自動完成功能是一個有趣的想法。我更喜歡readline和ncurses的鏈接(因爲我有時會在zsh和bash之間切換)。謝謝! – 2010-04-22 12:00:25

+0

標準readline需要完成。我沒有找到一個解決方案,但不需要鍵(即時搜索)。 – 2010-04-22 13:07:38