如何在 LINUX 中实现 AJAX(交互式)搜索以查找文件?

How to achieve AJAX(interactive) kind of SEARCH in LINUX to FIND files?

我有兴趣在终端中输入搜索关键字并能够看到输出 immediatelyinteractively。这意味着,就像在 google 中搜索一样,我希望在输入每个字符或单词后立即获得结果。

我想通过组合 WATCH 命令和 FIND 命令来做到这一点,但无法带来交互性。

假设,要在文件名中搜索名称为 'hint' 的文件,我使用命令

$ find | grep -i hint

这几乎给了我不错的输出结果。

但我想要的是相同的交互行为,这意味着无需重新键入命令而只需键入搜索字符串。

我想写一个 shell 脚本,它从 STDIN 读取并每 1 秒执行一次上述 PIPED-COMMAND。因此,无论我输入什么,它每次都将其作为命令的指令。但是 WATCH 命令不是交互式的。

我对以下类型的输出感兴趣:

$ hi
./hi
./hindi
./hint

$ hint
./hint

如果有人能用更好的替代方法代替我的 PSUEDO CODE 来帮助我,那也很好

偶然发现了这个老问题,觉得它很有趣,我想试一试。这个 BASH 脚本对我有用:

#!/bin/bash
# Set MINLEN to the minimum number of characters needed to start the    
# search. 
MINLEN=2
clear
echo "Start typing (minimum $MINLEN characters)..." 
# get one character without need for return 
while read -n 1 -s i
do
    # get ascii value of character to detect backspace
    n=`echo -n $i|od -i -An|tr -d " "`
    if (( $n == 127 )) # if character is a backspace...
    then 
        if (( ${#in} > 0 )) # ...and search string is not empty
        then 
            in=${in:0:${#in}-1} # shorten search string by one
            # could use ${in:0:-1} for bash >= 4.2 
        fi
    elif (( $n == 27 )) # if character is an escape...
    then
        exit 0 # ...then quit
    else # if any other char was typed... 
        in=$in$i # add it to the search string
    fi
    clear 
    echo "Search: \""$in"\"" # show search string on top of screen
    if (( ${#in} >= $MINLEN )) # if search string is long enough...
    then    
        find "$@" -iname "*$in*" # ...call find, pass it any parameters given
    fi
done

希望这能达到您的目的。我包含了一个 "start dir" 选项,因为如果您搜索整个主文件夹或其他内容,列表会变得非常笨拙。如果不需要,只需转储 </code> 即可。 使用 <code>$n 中的 ascii 值应该可以很容易地包含一些热键功能,例如退出或保存结果。

编辑:

如果您启动脚本,它将显示 "Start typing..." 并等待按键。如果搜索字符串足够长(由变量 MINLEN 定义),任何按键都会触发 find 运行 和当前搜索字符串(grep 似乎有点多余这里)。该脚本传递给 find 的任何参数。这允许更好的搜索结果和更短的结果列表。例如,-type d 将搜索限制在目录中,-xdev 将继续搜索当前文件系统等(请参阅 man find)。退格键会将搜索字符串缩短一个,而按 Escape 键会退出脚本。当前搜索字符串显示在顶部。我使用 -iname 来使搜索不区分大小写。将其更改为“-name”以获得区分大小写的行为。

下面的代码在 stdin 上输入,过滤方法作为 "" 中的宏,输出到 stdout

您可以使用它,例如,如下:

#Produce basic output, dynamically filter it in the terminal,
#and output the final, confirmed results to stdout
vi `find . | terminalFilter`

默认过滤宏是 grep -F "$pattern" 该脚本提供模式变量作为​​当前输入的内容。 作为当前输入内容的函数的即时结果显示在 终点站。当您按下 <Enter> 时,结果变为最终结果 并输出到 stdout.

#!/usr/bin/env bash

##terminalFilter

del=`printf "\x7f"` #backspace character

input="`cat`"       #create initial set from all input
#take the filter macro from the first argument or use
# 'grep -F "$pattern"'
filter=${1:-'grep -F "$pattern"'}  
pattern=  #what's inputted by the keyboard at any given time

printSelected(){
  echo "$input" | eval "$filter"
}
printScreen(){
  clear
  printSelected
  #Print search pattern at the bottom of the screen
  tput cup $(tput lines);  echo -n "PATTERN: $pattern"
} >/dev/tty   
#^only the confirmed results go `stdout`, this goes to the terminal only

printScreen
#read from the terminal as `cat` has already consumed the `stdin`
exec 0</dev/tty
while IFS=$'\n' read -s -n1 key; do
  case "$key" in 
    "$del") pattern="${pattern%?}";;  #backspace deletes the last character
        "") break;; #enter breaks the loop
         *) pattern="$pattern$key";; #everything else gets appended 
                                     #to the pattern string
  esac
  printScreen
done

clear
printSelected

fzf 是一个快速而强大的命令行模糊查找器,完全符合您的需求。

在这里查看:https://github.com/junegunn/fzf

对于您的示例,命令行上的简单 运行 fzf 应该可以正常工作。