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
2つの可能性があります。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*"
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は各デバイスで多くの操作を実行するため、私のシステムではかなり遅いです。
2番目の回避策では、両方のケースが一致するように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; }
}