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