我想編寫一些小腳本,它們在命令行上具有增量搜索功能(「儘可能找你」)。如何在命令行上實現增量式查找(find-as-you-type)搜索?
使用案例:我的手機通過USB連接,使用gammu --sendsms TEXT我可以寫短信。我把電話簿設置爲CSV,並且希望以此爲基礎進行搜索。
什麼是最簡單/最好的方法來做到這一點?它可能在bash/zsh/Perl/Python或任何其他腳本語言中。
編輯: 解決方案:修改Term::Complete做了我想要的。請參閱下面的答案。
我想編寫一些小腳本,它們在命令行上具有增量搜索功能(「儘可能找你」)。如何在命令行上實現增量式查找(find-as-you-type)搜索?
使用案例:我的手機通過USB連接,使用gammu --sendsms TEXT我可以寫短信。我把電話簿設置爲CSV,並且希望以此爲基礎進行搜索。
什麼是最簡單/最好的方法來做到這一點?它可能在bash/zsh/Perl/Python或任何其他腳本語言中。
編輯: 解決方案:修改Term::Complete做了我想要的。請參閱下面的答案。
繼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; }
我得到的印象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的自動完成功能的示例。
使用bash自動完成功能是一個有趣的想法。我更喜歡readline和ncurses的鏈接(因爲我有時會在zsh和bash之間切換)。謝謝! – 2010-04-22 12:00:25
標準readline需要完成
我認爲你會很難按下,除非你可以鉤住所有的按鍵。這些東西需要一個觸發器來調用完整的過程。 – 2010-04-22 13:20:21
+1漂亮的小黑客。 – 2010-04-22 18:35:26