나는 이 조각을 가지고 있습니다: 그 뒤에 있는 논리는 사용자가 -s 다음에 단어(예: -sdog)를 입력하기를 원한다는 것입니다. 그러나 이것은 작동하지 않습니다.
read -rp 'choose: ' choice
case $choice in
-a) echo you chose a;;
-s [a-z]+) echo you chose the word ${choice#"-s "};;
esac
매우 감사합니다! ! !
답변1
를 사용하여 두 단어를 읽으려면 read
두 개의 변수를 사용하십시오.
read -r -p 'Enter "-a" or "-s <word>": ' opt word
case $opt in
-a)
echo 'You picked "-a"'
;;
-s)
printf 'You picked "-s" with the word "%s"\n' "$word"
;;
*)
echo 'You picked neither "-a" nor "-s <word>"'
esac
코드가 작동하지 않는 이유는 확장 정규식을 패턴( -s [a-z]+
)으로 사용하고 있기 때문입니다. 이 문에서 사용되는 패턴은 case
파일 이름 와일드카드 패턴입니다. 그것들은 유사하지만 동일하지는 않습니다. 와일드카드 패턴은 정규식 패턴에 사용되는 것과 동일한 유형의 "반복 한정자"( )를 허용하지 않습니다 +
.
와일드카드 패턴을 사용하려면 를 사용할 수 있습니다 '-s '[a-z]*
. 즉, "문자열 -s
다음에 소문자를 사용한 다음무엇^-s [a-z].*
"(정규 표현식과 동일).
답변2
공백 문자를 이스케이프 처리해야 합니다(예:답변이전 질문).
Bash는 이를 "한 번 이상 발생"이 아닌 +
문자 그대로 해석합니다 . +
Bash의 패턴 일치 연산자는 정규 표현식과 다릅니다. 하나 이상의 항목을 일치시키려면 "확장 와일드카드" extglob
셸 옵션을 활성화하고 해당 +(...)
패턴을 사용할 수 있습니다.
[a-z]
범위 표현식이 소문자만 일치 하도록 하려면 (로케일 LC_COLLATE
이나 설정에 따라 달라질 수 있음) 셸 옵션을 LC_ALL
활성화할 수도 있습니다 .globasciiranges
shopt -s extglob
shopt -s globasciiranges
read -rp 'choose: ' choice
case $choice in
-a)
echo "you chose a"
;;
-s\ +([a-z]))
echo "you chose the word \"${choice#-s }\""
;;
*) echo "unknown choice \"$choice\""
esac
관련된:
- 패턴 매칭(Bash 참조 매뉴얼)
답변3
…)
Case 문에는 (따옴표가 없는) 공백이 있을 수 없습니다.
따라서 인용해야 합니다: \
, " "
또는 ' '
:
또한, Case 문의 일치는 정규 표현식이 아닌 패턴을 통해 수행됩니다. +
내부가 아님패턴 매칭, only *
이지만 이는 마지막 요소를 반복한다는 의미가 아니라 "모든 문자의 모든 문자"를 반복한다는 의미입니다. 귀하의 [a-z]+
목적은 소문자로만 구성된 단어를 일치시키는 것이라고 가정합니다 . 더 간단한 패턴 일치 문자열에 동일한 내용을 쓰는 것은 불가능합니다. 수행할 수 있는 작업은 다음과 같습니다.
read -rp 'choose: ' choice
case $choice in
-a) echo "you chose a";;
-s\ *[^a-z]*) echo "not a valid word selected";;
-s\ *) echo "you chose the word ${choice#"-s "}";;
*) echo "no choice made";;
esac