파일 이름 패턴 또는 디렉토리에 대한 bash 완료


13

bash 완성 스크립트를 설정하려고하는데 문제가 있습니다.

나열된 완성이 특정 확장자와 일치하는 파일 또는 디렉토리 (해당 확장자의 파일을 포함하거나 포함하지 않을 수 있음)가되도록 설정하고 싶습니다.

내가 겪고있는 문제는 파일 디렉토리 를 포함하는 완성을 얻을 수있는 유일한 방법 은과 같은 것을 사용하는 것입니다 -o plusdirs -f -X '!*.txt'. 그러나 bash가 디렉토리 중 하나를 완료하게하면 끝에 공백이 아니라 삭감.

_xyz()
{
  local cur=${COMP_WORDS[COMP_CWORD]}
  local prev=${COMP_WORDS[COMP_CWORD-1]}

  #COMPREPLY=( $( compgen -f -X '!*.txt' -- $cur ) )
  #COMPREPLY=( $( compgen -f -G '*.txt' -- $cur ) )
  #COMPREPLY=( $( compgen -o filenames -f -X '!*.txt' -- $cur ) )
  #COMPREPLY=( $( compgen -o dirnames  -f -X '!*.txt' -- $cur ) )
  COMPREPLY=( $( compgen -o plusdirs  -f -X '!*.txt' -- $cur ) )
  return 0
}

complete -F _xyz xyz

주석 처리 된 모든 줄도 시도했지만 디렉토리를 확장하지는 않습니다.

테스트를 위해 하나의 .txt 파일과 하나의 디렉토리 "dir"이있는 디렉토리 (이 디렉토리에는 .txt 파일이 있지만 아직 중요하지는 않음)에서 이것을 실행했습니다. xyz <TAB>이 함수를 입력 하면 디렉토리와 .txt 파일이 나열되지만 입력 xyz d<TAB>하면 xyz dir"공백"뒤에 공백이있는 것으로 확장됩니다 .

답변:


10

당신이 기능을 살펴보면 _cd()에서 의 / etc / bash_completion , 당신은 후행 자체를 슬래시를 추가하고 그 것을 볼 수 있습니다 전체 옵션으로 얻을라고 -o nospace위한 CD .

xyz에 대해서도 동일한 작업을 수행 할 수 있지만 찾은 일치 항목이 디렉토리 (있는 경우 슬래시 추가) 또는 파일 (있는 경우 공간 추가) 인 경우 별도로 확인해야합니다. 발견 된 모든 일치 항목을 처리하려면 for 루프에서 수행해야합니다.

또한 공백이 포함 된 경로를 올바르게 처리하려면 내부 파일 구분 기호를 줄 바꿈만으로 설정하고 공백을 이스케이프해야합니다. IFS=$'\n'와 함께 사용하면 printf %q거의 모든 문자를 완성 할 수 있습니다. 1 후행 공간을 벗어나지 않도록 특별한주의를 기울여야합니다.

다음이 작동합니다.

_xyz ()
{
    local IFS=$'\n'
    local LASTCHAR=' '

    COMPREPLY=($(compgen -o plusdirs -f -X '!*.txt' \
        -- "${COMP_WORDS[COMP_CWORD]}"))

    if [ ${#COMPREPLY[@]} = 1 ]; then
        [ -d "$COMPREPLY" ] && LASTCHAR=/
        COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR")
    else
        for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
            [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
        done
    fi

    return 0
}

complete -o nospace -F _xyz xyz

1 개행 문자는 내부 파일 구분 기호이므로 여기서 명백한 예외입니다.


이것은 훌륭하게 작동합니다 (내장되어 있지 않아도 너무 나쁩니다). 감사!
Rob I

1
"$ {COMP_WORDS [COMP_CWORD]}"대신 "$ 2"를 사용하지 않는 이유는 무엇입니까?
Edward Falk

3

이 간단한 솔루션은 다음과 같이 작동한다고 생각합니다.

  1. 끝나는 디렉토리 및 파일과 일치 .txt
  2. 파일 이름의 공백을 처리합니다
  3. 후행 공백없이 폴더 완성의 끝에 슬래시를 추가합니다
  4. 파일 완성 일치의 끝에 공간을 추가합니다

열쇠는 -o filenames완성하기 위해 지나 갔다. 이것은 RHEL 5.3의 GNU bash 3.2.25 및 osx의 GNU bash 4.3.18에서 테스트되었습니다.

_xyz()
{
  local cur=${COMP_WORDS[COMP_CWORD]}

  local IFS=$'\n'
  COMPREPLY=( $( compgen -o plusdirs  -f -X '!*.txt' -- $cur ) )
}

complete -o filenames -F _xyz xyz

예, 잘 작동하는 것 같습니다. 훨씬 더 간단합니다. 중요한 논쟁에 응해 주셔서 감사합니다!
Rob I
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.