하나의 인수, 폴더 이름,
에는 /secure/kernel_builds/
다음 세 개의 하위 폴더가 있습니다.
3.5.6/ 3.6.2/ source/
이제 가능한 모든 하위 폴더 이름을 나열하기 위해 자동 완성을 원하지만 명명된 하위 폴더 이름은 나열하지 않습니다 source
. 지금은 완성 단어가 숫자로 시작인지 확인하여 이 작업을 수행하는 매우 어리석은 방법을 사용하고 있습니다.
_avail_kernel_builds()
{
case $COMP_CWORD in
1)
if [[ "${COMP_WORDS[COMP_CWORD]}" =~ ^[0-9] ]];then
COMPREPLY=( /secure/kernel_builds/"${COMP_WORDS[COMP_CWORD]}"* )
else
COMPREPLY=( /secure/kernel_builds/"${COMP_WORDS[COMP_CWORD]}"[0-9]*/ )
fi
COMPREPLY=( "${COMPREPLY[@]#/secure/kernel_builds/}" )
COMPREPLY=( "${COMPREPLY[@]%/}" )
;;
esac
}
더 좋은 방법이 있나요?
답변1
내장 함수에는 이 목적을 위한 compgen
매개변수가 있습니다 :-X
-X 필터 모드 filterpat는 파일 이름 확장에 사용되는 패턴입니다. 목록에 적용됩니다 이전 옵션과 인수에 의해 생성된 가능한 완성, 그리고 각각 일치를 완료한 Filterpat는 목록에서 제거됩니다. 선두! 필터에 패턴을 무효화합니다. 이 경우 filterpat와 일치하지 않는 완성은 제거됩니다.
따라서 아마도 다음과 같이 할 수 있을 것입니다.
_avail_kernel_builds() {
case $COMP_CWORD in
1) COMPREPLY=( $(cd /secure/kernel_builds; compgen -d -X "source") ) ;;
esac
}
따라서 compgen -d
"현재 디렉터리의 폴더를 나열합니다"라고 -X "source"
말하고 "...그러나 "source"라는 이름의 항목은 필터링합니다.
답변2
루프에서 원하는 문자열을 확인할 수 있습니다.
declare -a accept
declare -a reject
for s in "${COMPREPLY[@]}"; do
if [[ "$s" =~ want ]]; then
accept=( "${accept[@]}" "$s" )
else
reject=( "${reject[@]}" "$s" )
fi
done