색인을 기반으로 문자열에서 단어를 가져오는 더 효율적인 방법은 무엇입니까?

색인을 기반으로 문자열에서 단어를 가져오는 더 효율적인 방법은 무엇입니까?

콜론이 있어도 깨지지 않는 Bash 완성 스크립트를 작성하려고 합니다. 이를 위해 COMP_LINE을 사용하여 명령의 문자열을 결정하고 COMP_POINT를 사용자가 현재 가리키는 명령의 문자에 대한 인덱스로 사용합니다.

이 두 변수를 사용하여 사용자가 현재 어떤 단어를 완성하려고 하는지 파악하고 싶습니다. 이는 일반적으로 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)를 확인하고 다음 네 가지 규칙에 따라 현재 가리키는 단어를 결정합니다.

  1. char과 prev가 모두 공백 문자인 경우 'word'를 공백으로 설정합니다.

  2. char이 공백이고 prev가 공백이 아닌 문자인 경우 'prev'가 단어의 끝으로 사용됩니다. prev까지 하위 문자열을 추출한 다음 하위 문자열의 시작부터 공백 포함까지 모든 항목을 제거합니다.

  3. char가 공백이 아닌 문자이지만 prev가 공백인 경우 'char'가 단어의 시작으로 사용됩니다. prev까지 하위 문자열을 추출한 다음 하위 문자열 끝부터 공백 포함까지 모든 항목을 제거합니다.

  4. char 및 prev가 모두 공백이 아닌 문자인 경우 'char'는 단어의 중간 또는 끝으로 처리됩니다. 먼저 "char"부터 문자열 끝까지 부분 문자열을 가져온 다음 해당 부분 문자열의 시작 부분부터 공백이 포함될 때까지 가장 짧은 텍스트 인스턴스를 제거합니다. 그런 다음 삭제저것원래 문자열에서 부분 문자열을 추출하여 단어의 모든 내용을 가져옵니다. 마지막부터저것하위 문자열에서 단어를 얻으려면 모든 것(공백 포함)을 제거하세요.


원래나는 이것이 가장 효율적인 해결책이라고 생각하지 않습니다. 질문으로 설명하는 것조차 복잡합니다. 확실히 해당 단어의 색인을 기반으로 문자열에서 전체 단어를 가져오는 더 좋고 멋진 방법이 있습니까?

누구든지 이 문제를 해결하는 더 나은 방법에 대한 제안을 제공할 수 있습니까? 그렇지 않은 경우 내 솔루션을 최적화할 수 있는 방법이 있습니까?

관련 정보