Scripting 如何在命令行上实现增量(键入时查找)搜索?

Scripting 如何在命令行上实现增量(键入时查找)搜索?,scripting,Scripting,我想写一些小脚本,在命令行上进行增量搜索(键入时查找) 用例:我的手机通过USB连接,使用gammu--sendsms文本,我可以写短信。我将电话簿设置为CSV,并希望以此作为输入进行搜索 做这件事最简单/最好的方法是什么?它可以是bash/zsh/Perl/Python或任何其他脚本语言 编辑: 解决方案:我做了我想做的。请参见下面的答案。我得到的印象是支持这种事情。不过,我自己也没用过。自定义自动完成,这也可以很容易地在C中完成。还有一个用于readline的 给出了Python中的示例,其

我想写一些小脚本,在命令行上进行增量搜索(键入时查找)

用例:我的手机通过USB连接,使用gammu--sendsms文本,我可以写短信。我将电话簿设置为CSV,并希望以此作为输入进行搜索

做这件事最简单/最好的方法是什么?它可以是bash/zsh/Perl/Python或任何其他脚本语言

编辑:
解决方案:我做了我想做的。请参见下面的答案。

我得到的印象是支持这种事情。不过,我自己也没用过。自定义自动完成,这也可以很容易地在C中完成。还有一个用于readline的

给出了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)
import readline
def完成符(文本、状态):
选项=[x在地址中,其中x.startswith(文本)]
如果状态

在Bash上自动完成可能会有所帮助。本文还提供了编程bash的自动完成功能的示例。

根据Aiden Bell的提示,我在Perl中尝试了Readline。 解决方案1使用Term::Complete(我认为CPAN也使用):

使用术语::完成;
我的$F;
开放式($F,“>”;
my$OUT=$term->OUT | STDOUT;
while(已定义(my$input=$term->readline($prompt))){
我的($name,$number)=拆分(/\t/,$input);
打印(“向$name($number)发送短信)。\n”);
系统(“SudoGammu--sendsms文本$number”);
}
这个解决方案仍然需要一个完整的解决方案

编辑:最终解决方案 修改Term::Complete()确实会让我即时完成

源代码: 解决方案1适用于此修改。如果有人可以使用,我会将整个样本放到其他地方

对Completion.pm的修改(仅对Control-D和\每个字符重复使用其代码):

170C172189

my$redo=0;
@match=grep(/^\Q$return/,@cmp_lst);
除非($#匹配<0){
$l=长度($test=移位(@match));
foreach$cmp(@match){
直到(substr($cmp,0,$l)均衡substr($test,0,$l)){
$l--;
}
}
打印(“\a”);
打印($test=substr($test,$r,$l-$r));
$redo=$l-$r==0;
if($redo){print(join(“\r\n”),“”,grep(/^\Q$return/,@cmp_lst)),“\r\n”);}
$r=长度($return.=$test);
}
if($redo){redo LOOP;}else{last CASE;}


使用bash自动完成功能是一个有趣的想法。我更喜欢readline和ncurses的链接(因为我有时会在zsh和bash之间切换)。谢谢!需要完成标准readline。我还没有找到一个使用readline的解决方案,它不需要键(可以动态搜索).我想你会很紧张,除非你能抓住所有的击键。这些东西需要一个触发器来调用整个过程。
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");
}
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");
}
        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; }