var
주어진 변수(예를 들어) 가 주어진 문자열 목록에 있는 단어로 시작하는지 확인하는 함수를 작성하고 싶습니다 . 이 목록은 변경되지 않습니다.
인스턴스화 하기 위해 , 또는 var
로 시작하는지 확인하고 싶다고 가정해 보겠습니다 aa
.abc
3@3
var
또한 문자가 포함되어 있는지 확인하고 싶습니다 >
.
이 함수가 호출된다고 가정하면 check_func
내 의도된 용도는 다음과 같습니다.
if check_func "$var"; then
do stuff
fi
aardvark
예를 들어 , 및 에 대해 " 무언가를 수행" 해야 합니다 abcdef
.[email protected]
12>5
나는 보았다이 문제사용자가 저작물의 일부를 제공하는 상황:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
위에서 언급한 목록을 반복하고 이 기능을 사용하겠다는 생각입니다. 내 어려움은 종료(또는 복귀에 대한 대안)가 이 작업을 어떻게 수행해야 하는지 정확히 이해하지 못하는 것입니다.
답변1
check_prefixes () {
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
}
check_contains_gt () {
value=$1
case $value in
*">"*) return 0
esac
return 1
}
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixes\n' "$var"
fi
테스트를 두 가지 기능으로 나누었습니다. case ... esac
이것이 결정되면 둘 다 사용되며 성공(0)을 반환합니다. 일치하는 항목이 없으면 failure(1)이 반환됩니다.
접두사 목록을 동적 목록처럼 만들려면 첫 번째 함수를 다음과 같이 작성할 수 있습니다.
check_prefixes () {
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
}
(확인할 값은 첫 번째 매개변수입니다. 이를 함수의 매개변수 목록에 저장한 value
다음 shift
함수의 매개변수 목록에서 제거합니다. 그런 다음 나머지 매개변수를 반복합니다.) 그런 다음 다음과 같이 호출합니다.
check_prefixes "$var" aa abc 3@3
두 번째 기능도 비슷한 방식으로 변경할 수 있습니다.
check_contains () {
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
}
(임의의 하위 문자열을 확인하십시오) 또는
check_contains_oneof () {
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
}
(여러 하위 문자열 중 하나를 확인하십시오)
답변2
배쉬의 경우:
정규식의 속성을 사용하면 아무것도 start
포함하거나 포함 ^
하지 않고 작성할 수 있습니다 contain
.
확인할 정규식 목록시작그리고 aa
abc
또는 3@3
그리고포함하다 >
예:
^aa ^abc ^3@3 >
그것을 만들다적절하게목록을 인용하고 bash에게 정규식( =~
)을 사용하도록 요청하세요.
check_func() {
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
}
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
함수에는 일치 목록과 변수 이름이 하드코딩되어 있습니다.
배열 변수의 정규식 목록과 첫 번째 인수를 테스트할 값이 제공됩니다.
check_func() {
local matched; matched=1
for t in "${test_regex[@]}"; do
[[ $1 =~ $t ]] && { matched=0; break; }
done
return "$matched"
}
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
이 함수는 변수 이름(값 대신)을 첫 번째 인수로 사용하도록 더욱 향상될 수 있습니다.
POSIX
posix 쉘에는 정규 표현식이 없고 테스트할 수 있는 유일한 방법은 Case 문이므로 Case 문을 사용해야 합니다. 불행하게도 이전 쉘([확장 glob 사용 가능 없음][1])에서는 모든 테스트를 반복해야 합니다. 그리고 glob은 다음과 같아야 합니다.
'aa*' 'abc*' '3@3*' '*>*'
여러 glob에 대해 여러 입력 문자열을 테스트하는 예제 스크립트:
check_func() { :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
}
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for \"$var\""
fi
done
이 함수의 간단한 버전은 정확히 원하는 작업을 수행합니다.
check_func() { :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
}
답변3
이 명령문의 역할은 case
두 번째 매개변수를 함수( $2
)에 전달하는 것입니다. 패턴과 일치하면 "$1"*
, 즉 함수의 첫 번째 매개변수 뒤에 아무 것도 없으면 true
명령문이 실행되고 종료됩니다 case
. true
아무 작업도 수행하지 않고 상태 0을 반환합니다. 그렇지 않고 일치하는 항목 *
, 즉 아무것도 없으면 false
명령문이 실행되고 종료됩니다 case
. false
아무 작업도 수행하지 않고 상태 1을 반환합니다. 따라서 case
두 번째 매개변수가 첫 번째 매개변수로 시작하면 명령문의 상태는 0이고, 그렇지 않으면 1입니다. 이것이 함수의 마지막(그리고 유일한) 명령문이므로 함수는 두 번째 인수가 첫 번째 인수로 시작하면 0을 반환하고 그렇지 않으면 1을 반환합니다.
조건문(예: if
셸의 조건문)이 0을 반환하면 해당 문은 true로 간주되고, 그렇지 않으면 false로 간주됩니다. 따라서 값이 다음으로 시작하면 그렇지 않으면 인쇄하십시오 if beginswith "$var" "string"; then echo yes; else echo no; fi
.yes
var
string
no
이 함수를 작성하는 방법에는 여러 가지가 있습니다. 예를 들어 작성자는 함수의 마지막 문이므로 and 대신 return 0
or를 사용할 수 있습니다. 함수는 함수 매개변수( 및 )에 대한 참조를 사용하려는 문자열 로 변경하여 함수에 래핑하지 않고 함수 본문을 직접 사용할 수 있는 방식으로 작성되었습니다 .return 1
true
false
$1
$2
여러 접두사를 허용하려면 루프에서 반복합니다. 일치하는 접두사가 발견되면 true(0) 상태의 함수에서 반환됩니다. 일치하는 접두사가 없으면 오류 상태(일반적으로 1)가 반환됩니다.
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with () {
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
}
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
접미사를 테스트하려면 *"$suffix"
대신 패턴을 "$prefix"*
사용하십시오. 하위 문자열을 테스트하려면 *"$substring"*
여기에서 큰따옴표를 사용해야 합니다. 그렇지 않으면 변수가 패턴으로 해석됩니다. 예를 들어:
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
답변4
질문의 설명에 따라 수정되었습니다. 이것은 덜 우아하고 덜 유연하지만 다른 답변보다 더 컴팩트합니다.
check_func() {
case "$1" in
( aa* | abc* | 3@3* | *">"*)
return 0
esac
return 1
}
aardvark
이는 , abcdef
및 에 대해 true를 반환합니다 . 물론, , 가 있습니다 .[email protected]
12>5
aard>vark
abc<def>ghi
3@3>3