안녕하세요. 입력에 @ 기호가 포함되어 있는지 확인하는 bash 스크립트를 작성하려고 합니다. 저는 bash를 처음 접하는 사람이므로 모든 오류를 용서해 주세요! 지금까지 나는 다음을 가지고 있습니다 :
var1="@"
var2="INPUT"
echo "input"
read INPUT
if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
답변1
내장된 셸 기능을 사용하여 사용자 입력이 포함되어 있는지 확인하는 옵션이 있지만 @
(다른 답변에 잘 문서화되어 있음) 이를 수행하는 또 다른 합리적인 방법은 외부를 사용하는 것입니다.grep
공익사업:
#!/usr/bin/env bash
read -erp '> '
if grep -q @ <<<"$REPLY"; then
echo pass
else
echo fail
fi
-q
일치하는 줄을 인쇄하지 못하도록 플래그 를 전달합니다 grep
. (또한 일치하는 항목을 찾은 후 더 이상 줄을 읽지 못하게 하지만 입력 줄이 하나뿐이므로 여기서는 차이가 없습니다.)
if
구문을 다음과 같이 단축하고 싶은 유혹이 있지만 grep -q @ <<<"$REPLY" && echo pass || echo fail
의도적으로 그렇게 하는 것을 피했습니다.
- 이 경우, 아마도 괜찮을 것입니다. 왜냐하면 잘못된 단어가 인쇄되는 유일한 방법은
pass
인쇄되어야 했지만echo
인쇄에 실패한 경우이기 때문입니다. 그러면 아마도 echofail
도 인쇄에 실패할 것입니다. - Short-circuit
&&
은||
종종 그 자체로 적절합니다. (저는 종종 이를 줄여서 사용합니다.if
없이절else
) 마치 그것들을 함께 사용하는 것처럼삼항만약에운영자사실 좋은 습관은 아니다. 일부 명령은 할 수 없지만실패하다,echo
~할 수 있다. - 사용자가리디렉션스크립트의 출력을 쓸 수 없는 파일이나 장치로 보내거나 손상된 파일이나 장치에서 사용합니다.관로, echo 및 텍스트를 출력하는 기타 명령은 실패를 반환할 수 있으며 이로 인해 표현식
&&
이 실패하고 표현식의 오른쪽이||
실행됩니다. - 로 실행하여 쓸 수 없는 출력 장치가 있는 경우 스크립트의 동작을 테스트할 수 있습니다
>/dev/full
.
해당 스크립트는 몇 가지 bash 기능을 사용합니다.
-e
GNU readline을 활성화하므로 사용자는 화살표 키를 사용하여 커서를 왼쪽 및 오른쪽으로 이동하여 입력하는 동안 입력 내용을 편집할 수 있습니다.- Bash에서는 변수가 제공되지 않은 경우
read
자동으로 사용자 입력을 변수에 넣습니다 .REPLY
- ㅏ여기 문자열with는
<<<
사용자의 입력을 에 전달하는 편리한 방법입니다grep
. - 배쉬와일부dash와 같은 다른 Bourne 스타일 쉘은
-p
. 하지만POSIX 호환 쉘은 이해만 하면 됩니다.-r
. 그리고 ksh와 같은 일부에서는-p
다른 의미를 갖습니다.
(덕분에게이라그 두 가지를 모두 지적해주셔서-p
가끔 부재중그리고 그거항상 "즉시"를 의미하는 것은 아닙니다.)
Bash가 설치되지 않은 다른 OS에 이식 가능한 스크립트를 원하는 경우 다음을 사용할 수 있습니다.
#!/bin/sh
printf '> '
read -r line
if printf '%s' "$line" | grep -q @; then
echo pass
else
echo fail
fi
원하는 경우 다음을 사용하여 사용자 입력을 변수에 저장하는 것을 건너뛸 수 있습니다.head
대신에 read
:
#!/bin/sh
printf '> '
if head -1 | grep -q @; then
echo pass
else
echo fail
fi
처럼게이라가 언급됨, head -n 1
더 나은 구문으로 간주될 수 있습니다 head -1
.공식적으로는 쓸모가 없다(현재 sed
구현 또는 적어도 GNU sed는 -1
최신 버전에서 지원하지만 일부 아주 오래된 sed
구현은 지원하지 않습니다 -n 1
.)
처럼문서head
sed
최대 이식성을 위해 대신 사용할 수 있다고 말합니다 .
#!/bin/sh
printf '> '
if sed 1q | grep -q @; then
echo pass
else
echo fail
fi
답변2
이 bash
코드는 입력을 읽고 입력에 @
기호가 포함된 경우 "Pass" 신호를 보냅니다.
read -p "Input: " var
[ "${var//[^@]/}" ] && echo Pass || echo Fail
노트:
[ "$var" ]
배쉬 테스트입니다. 문자열이$var
비어 있지 않으면 true를 반환합니다.Bash의 기능 중 하나는 패턴 대체입니다. 처럼 보입니다
${var//pattern/string}
. 모든 발생을pattern
invar
으로 대체합니다string
. 우리의 경우에는 모든 문자와 일치하는 정규식pattern
입니다 .[^@]
제외하고@
. 따라서 하나 이상의 가 포함되어${var//[^@]/}
있지 않으면 빈 문자열을 반환합니다 .var
@
위의 두 가지를 결합합니다.
[ "${var//[^@]/}" ]
이 테스트는 이
${var//[^@]/}
비어 있지 않은 경우에만 성공하고 하나 이상의 가 포함된${var//[^@]/}
경우에만 비어 있지 않습니다 .var
@
명시적인 if-then-else 사용:
read -p "Input: " var
if [ "${var//[^@]/}" ]
then
echo Pass
else
echo Fail
fi
POSIX 쉘
다음은 dash
( /bin/sh
)에서 작동하며 모든 POSIX 셸에서 작동해야 합니다.
printf "Input: "
read var
case "$var" in
*@*) echo Pass
;;
*) echo Fail
;;
esac
POSIX 쉘은 -p
다음 옵션을 지원하지 않습니다.read
. 따라서 대신 printf
및 의 조합이 read
사용됩니다. 또한 의 고급 변수 확장 기능이 부족하여 bash
이 case
명령문을 전역 일치에 사용할 수 있습니다.
안드로이드 셸
내 안드로이드에서 기본 셸을 사용하면 다음이 작동합니다.
echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
echo Pass
else
echo Fail
답변3
bash에서 선호되는 방법은 [[ ... ]]
.
#bash
read -rp "Input: " input
if [[ $input = *@* ]]; then
printf '<%s> contains @\n' "$input"
fi
스크립트 의 경우 대신 sh
사용할 수 있습니다 case
.
#sh
printf 'Input: '
read -r input
case $input in
*@*) printf '<%s> contains @\n' "$input" ;;
esac
또한 참조하십시오테스트 및 조건부Bash 가이드의 장.
답변4
최신 버전의 bash에서는 다음을 사용할 수 있습니다.정규식 일치확장된 테스트 연산자를 통해 =~
:
$ read -p "input: " input
input: quertyuiop
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
no match
$
$ read -p "input: " input
input: qwerty@uiop
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
match
POSIX 호환 시스템에서 작동해야 하는 대안은 expr
예를 들어 셸에서 사용하는 것입니다 dash
.
$ read input
qwertyuiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
no match
$
$ read input
qwerty@uiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
match
$