자동 완성 시스템 단위 이름을 대소 문자를 구분하지 않게 만드는 방법은 무엇입니까?

자동 완성 시스템 단위 이름을 대소 문자를 구분하지 않게 만드는 방법은 무엇입니까?

Bash 자동 완성은 시스템 단위 이름에 대한 PHP와 유사한 명명 규칙에 많은 도움이 됩니다. Kebab-case, snake_case, camelCase의 혼합 문제를 완전히 해결했습니다.

하지만 첫 글자의 잘못된 대문자 사용과 같은 문제로 인해 여전히 좌절감을 느낍니다. ... t<tab><tab>...sigh...<backspace>T<tab>Thunderbolt그리고 B<tab><tab>...sigh...<backspace>b<tab>bluetooth네트워크 관리자 이름 바꾸기를 시작하지도 마세요 :)

나는 보았다배쉬 완료 파일사용systemctl $1 list-units --all "$2*";

가장 좋은 접근 방식은 무엇입니까 nocaseglob?

답변1

두 가지 가능성이 있습니다. list-units모든 셀을 나열하고 나중에 파이프라인에서 Anycase 일치를 수행하거나 $2*glob을 Anycase glob으로 변환하는 것입니다.

먼저, 쉽게 읽을 수 있도록 다시 들여쓰기하여 링크에 현재 코드를 표시하겠습니다.

__get_all_units(){
 { __systemctl $1 list-unit-files "$2*"
   __systemctl $1 list-units --all "$2*"
 } |
 { while read -r a b
   do echo " $a"
   done
 }
}

아마도 printf대신 사용해야 echo하지만 우리는 이를 무시할 것입니다.

첫 번째 솔루션의 경우 "$2*"두 번 삭제하고 while 루프를 변경합니다.

__get_all_units(){
 { __systemctl $1 list-unit-files
   __systemctl $1 list-units --all
 } |
 { shopt -s nocasematch
   while read -r a b
   do if [[ "$a" == $2* ]]
      then echo " $a"
      fi
   done
 }
}

이것은 작동하지만 systemd가 각 장치에서 많은 작업을 수행하기 때문에 내 시스템에서는 상당히 느립니다.

두 번째 해결 방법의 경우 두 경우가 모두 일치하도록 glob 패턴을 대체하는 함수(예 n: ) 를 만듭니다.[nN]

myanycaseglob(){
 local pat=$1 len=${#1} result i ch
 for i in $(eval echo {0..$(($len-1))})
 do ch=${pat:$i:1}
    if [[ "$ch" == [a-zA-Z] ]]
    then result="$result[${ch,*}${ch^*}]"
    else result="$result$ch"
    fi
 done
 echo "$result"
}

위의 코드는 bash를 사용하여 ${ch,*}각 문자를 소문자 또는 ${ch^*}대문자로 변환합니다. 그러면 일치 항목을 나열하는 함수는 간단합니다.

__get_all_units() { 
 local anywant=$(myanycaseglob "$2")
 { __systemctl $1 list-unit-files "$anywant*" 
   __systemctl $1 list-units --all "$anywant*"
 } |
 { while read -r a b; do echo " $a"; done; }
}

관련 정보