我正在尝试模仿bash文件的完成情况 假设我有以下文件:
TEST1
TEST2
输入字符串为“ te ”我想获得输出“ test ”
这是我当前的尝试($c
是输入字符串):
l=1
q="$c"
for j in $(ls -A | grep "^$c"); do
if [ "${j/$c}" != "$j" ]; then
n=$(ls -A | grep ^$j | wc -l)
if [ $n -gt $l ]; then
q="$j"
fi
fi
done
c="$q"
echo $c
感谢您的帮助
答案 0 :(得分:1)
我倾向于认为没有办法从完成引擎中获取它,因为它不是GNU Bash的一部分而是Readline。但至少我们可以使用compgen
获取可能的完成列表。找到最长公共前缀的实现应该不是问题。所以......
#!/bin/bash
SCRIPTNAME="${0##*/}"
USAGE="Usage: $SCRIPTNAME <prefix>
Print common prefix of possible file name completions. Like <TAB> but to
stdout."
(( $# == 1 )) || { printf >&2 '%s\n' "$USAGE"; exit 1; }
PREFIX="$1"
commonprefix() {
(( $# >= 2 )) || {
echo "$1"
return 0
}
local -i i N M
for ((i=0; i<=${#1}; i++)); do
for ((N=1; N<=$#-1; N++)); do
let M=$N+1
[[ ${!N:i:1} == ${!M:i:1} ]] || break 2
done
done
echo "${1:0:i}"
}
readarray -t COMPLETIONS < <(compgen -f "$PREFIX")
commonprefix "${COMPLETIONS[@]}"
答案 1 :(得分:0)
为了表明你正在考虑正确的方向,我让你的代码工作:
#!/bin/bash
c=$1
q="$c"
for j in $c*; do
if [ "${j/$c}" != "$j" ]; then
startn=$(ls -1A | grep -c "^${j:0:$((${#c} + 1))}")
for (( i=${#c}; i <= ${#j}; i++ )); do
n=$(ls -1A | grep -c "^${j:0:$i}")
if [ "$n" -lt "$startn" ]; then
q="${j:0:$((i - 1))}"
elif [ "$n" -le "$startn" ]; then
q="${j:0:$i}"
fi
done
fi
done
c="$q"
echo "$c"
但是,它只是一个概念证明,不使用它。请参阅德米特里亚历山德罗夫的答案以获得一个很好的解决方案。
答案 2 :(得分:0)
虽然德米特里亚历山德罗夫已经提供了更好的解决方案,但我仍然希望在等待答案时发布我自己的一个:
l=1
while [ -n $l ]; do
l=${#c}
a=$(ls -A | grep "^$c" | wc -l)
q=$c
for i in $(ls -A | grep "^$q"); do
if [ $i == $q ]; then
unset l
break
else
v=$(ls -A | grep "^$q${i:$l:1}" | wc -l)
if [ $v == $a ]; then
q="$c${i:$l:1}"
break
fi
fi
done
if [ $c == $q ]; then break; fi
c=$q
done
echo $c
它适用于我的所有测试,但速度很慢(尽管可以优化)。