コロンがあっても壊れないBash完成スクリプトを作成しようとしています。これを行うには、COMP_LINEを使用してコマンドの文字列を決定し、COMP_POINTをユーザーが現在指しているコマンドの文字のインデックスとして使用します。
これら2つの変数を使用して、ユーザーが現在どの単語を完成させようとしているのかを把握したいと思います。これは通常、COMP_CWORD変数が配列へのポインタとして機能するCOMP_WORDS配列を使用して行われます。問題はCOMP_WORDSが文字列をコロンに分割するので、コマンドは次のようになります。
dothis foo:bar
COMP_WORDSから次のように読みます。
('dothis' 'foo' ':' 'bar')
私はこの動作を望まないので、この問題を解決しようとしています。
次のように、Bash変数に格納されたコマンドがあるとします。
apple banana carrot:cucumber durian
上記の問題に対する私の現在の解決策は次のとおりです。説明はコードの下にあります。正直なところ、コードはもっと簡単だと思います。
#!/bin/bash
str="apple banana carrot:cucumber durian"
cur=29
char=${str:$cur:1} # Current character being pointed to
prev=${str:$cur-1:1} # Previous character
if [[ $char == [[:space:]] ]]; then
if [[ $prev == [[:space:]] ]]; then
# Rule 1 - Char and prev are whitespace
# apple banana carrot:cucumber durian
# ^ Char = ' ' Prev = ' '
word=""
else
# Rule 2 - Char is whitespace, prev is not
# apple banana
# ^ Char = ' ' Prev = 'e'
# Means prev is the last character of the word
slice="${str::$cur}"
word="${slice##* }" # 'apple'
fi
else
if [[ $prev == [[:space:]] ]]; then
# Rule 3 - Char is not whitespace, prev is whitespace
# apple banana carrot:cucumber
# ^ Char = 'c' Prev = ' '
slice="${str:$cur}"
word="${slice%% *}" # 'carrot:cucumber'
else
# Rule 4 - Char and prev are not whitespace
# apple banana
# ^ Char = 'a' Prev = 'n'
end="${str:$cur}"
end="${end#* }"
slice="${str% $end}"
word="${slice##* }" # 'banana'
fi
fi
echo "Word: <$word>"
その機能は次のとおりです。インデックスの文字(char)とその前の文字(prev)を確認し、次の4つの規則に従って現在指している単語を決定します。
charとprevの両方が空白文字の場合は、「word」を空白に設定します。
charが空白で、prevが空白以外の文字の場合、「prev」は単語の終わりとして使用されます。 prev までの部分文字列を抽出し、その部分文字列の先頭から空白を含むすべての項目を削除します。
char が空白以外の文字であり、prev が空白の場合、 'char' は単語の先頭として使用されます。 prev までの部分文字列を抽出し、部分文字列の末尾から空白を含むすべての項目を削除します。
charとprevが共に空白以外の文字の場合、 'char'は単語の中間または末尾として扱われます。まず、「char」から文字列の最後まで部分文字列を取得し、その部分文字列の先頭から空白が含まれるまで、最短のテキストインスタンスを削除します。その後、削除それ元の文字列から部分文字列を抽出して、単語の内容をすべて取得します。最後からそれ部分文字列から単語を取得するには、すべて(スペースを含む)を削除してください。
オリジナル私はこれが最も効率的な解決策だとは思わない。質問で説明することさえ複雑です。確かに、その単語のインデックスに基づいて文字列から単語全体を取得するためのより良い、素晴らしい方法はありますか?
誰もがこの問題を解決するためのより良い方法の提案を提供できますか?それ以外の場合、私のソリューションを最適化する方法はありますか?