입력에 @가 있는지 확인하는 bash 스크립트

입력에 @가 있는지 확인하는 bash 스크립트

안녕하세요. 입력에 @ 기호가 포함되어 있는지 확인하는 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인쇄에 실패한 경우이기 때문입니다. 그러면 아마도 echo fail도 인쇄에 실패할 것입니다.
  • Short-circuit &&||종종 그 자체로 적절합니다. (저는 종종 이를 줄여서 사용합니다.if 없이else) 마치 그것들을 함께 사용하는 것처럼삼항만약에운영자사실 좋은 습관은 아니다. 일부 명령은 할 수 없지만실패하다,echo ~할 수 있다.
  • 사용자가리디렉션스크립트의 출력을 쓸 수 없는 파일이나 장치로 보내거나 손상된 파일이나 장치에서 사용합니다.관로, echo 및 텍스트를 출력하는 기타 명령은 실패를 반환할 수 있으며 이로 인해 표현식 &&이 실패하고 표현식의 오른쪽이 ||실행됩니다.
  • 로 실행하여 쓸 수 없는 출력 장치가 있는 경우 스크립트의 동작을 테스트할 수 있습니다 >/dev/full.

해당 스크립트는 몇 가지 bash 기능을 사용합니다.

  • -eGNU 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.)

처럼문서headsed최대 이식성을 위해 대신 사용할 수 있다고 말합니다 .

#!/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}. 모든 발생을 patternin var으로 대체합니다 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사용됩니다. 또한 의 고급 변수 확장 기능이 부족하여 bashcase명령문을 전역 일치에 사용할 수 있습니다.

안드로이드 셸

내 안드로이드에서 기본 셸을 사용하면 다음이 작동합니다.

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
$ 

관련 정보