파일 이름의 어느 곳에서나 일치하는 것은 다소 복잡합니다. 실제로는 그다지 유용하지는 않습니다. 파일 이름의 시작 부분에서의 매칭은 더 이해하기 쉽고 재귀 적으로 구현하는 것이 훨씬 쉽습니다.
이제 find를 요구 사항으로 언급했지만 bash (버전 4.0부터)는 재귀 적으로 파일을 찾을 수 있으며 bash가 해당 부분을 수행하게하는 것이 더 효율적이어야합니다. bash에서 재귀 적으로 일치 시키려면 shopt -s globstar
을 실행하여 globstar 쉘 옵션을 사용하면 두 개의 연속 된 별표 **
이 재귀 적으로 일치합니다.
다음은 git 저장소 내에서 파일을 재귀 적으로 일치시키려는 경우 실제로 우리가 git 저장소에 있다는 것을 감지하는 것이 가장 좋습니다. 그렇지 않으면 우연히 /
에서 bash가 전체 파일 시스템을 검색하기를 기다리는 동안 프롬프트가 멈 춥니 다. 다음 함수는 우리가 자식 저장소에 있는지 결정할 때 상당히 효율적이어야합니다. 주어진 현재 작업 디렉토리, 예를 들면./foo/bar/baz
일 경우 /foo/bar/baz/.git
, /foo/bar/.git
, /foo/.git
, /.git
을 찾아서 찾으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
isgit() {
local p=$PWD
while [[ $p ]]; do
[[ -d $p/.git ]] && return
p=${p%/*}
done
return 1
}
은 단순화하기 위해, 우리의 완료를 추가하는 gadd
명령을 만듭니다. 완료 기능은 명령의 첫 번째 단어에만 적용 할 수 있습니다. 예 : git
에 대한 완료를 추가 할 수 있지만 git add
에 대한 완료를 추가 할 수 없으므로 git add
을 하나의 단어로 바꾸는 새로운 명령을 만듭니다.
gadd() {
git add "[email protected]"
}
이제 실제 완성 기능을 위해. Tab 키를 눌러 트리거하면 함수가 세 개의 인수로 호출됩니다. $1
은 완료되는 명령이고 $2
은 완료되는 명령 행의 현재 단어이고 $3
은 그 행의 이전 단어입니다. 따라서 우리가 검색하고자하는 파일은 glob **/"$2"*
과 일치합니다. "$2"
으로 시작하는 모든 파일. 이 파일 이름을 반복하여 COMPREPLY 배열에 추가합니다. 함수가 완료 될 때 COMPREPLY 배열에 하나의 값만 포함되어 있으면 해당 값으로 바뀝니다. 둘 이상의 값이 포함 된 경우 다른 탭을 탭하여 모든 일치 항목의 목록을 가져옵니다.
shopt -s globstar
_git_add_complete() {
local file
isgit || return
for file in **/"$2"*; do
# If the glob doesn't match, we'll get the glob itself, so make sure
# we have an existing file
[[ -e $file ]] || continue
# If it's a directory, add a trailing/
[[ -d $file ]] && file+=/
COMPREPLY+=("$file")
done
}
complete -F _git_add_complete gadd
는, 새로운 터미널을 열고, 당신의
~/.bashrc
에 위의 세 가지 코드 블록을 추가 자식 저장소를 입력하고
gadd something<tab>
을 시도합니다.
굉장합니다. 감사! –