이것이 내가 시도하는 것입니다:
#!/bin/sh
contains() {
if $(echo $1 | grep -c $2) ; then
echo "0" # contains
else
echo "1" # not contains
fi
}
myString=$1
mySubsting=$2
contains $myString '$mySubsting'
실행 예는 다음과 같습니다.
# sh ./myScript abcdef bc
./myTest: line 3: 0: command not found
1
편집하다:
원래 질문: Bourne Shell에서 문자열에 하위 문자열이 포함되어 있는지 확인하는 방법은 무엇입니까?
이것이 내가 시도하는 것입니다:
#!/bin/sh
if echo $1 | grep -q $2
then
echo "0"
else
echo "1"
fi
실행 예는 다음과 같습니다.
$ sh ./myTest "$(systemctl status ntp)" "Active: active"
grep: active: No such file or directory
1
문자열에 다른 문자열이 포함되어 있는지 올바르게 확인하는 방법은 무엇입니까?
답변1
함수를 포함하는 이식 가능한(dash, bash, ksh 등) 스크립트:
#!/bin/sh
contains() { if [ "$1" ] && # Is there a source string.
[ "$2" ] && # Is there a substring.
[ -z "${1##*"$2"*}" ]; # Test substring in source.
then echo 0; # Print a "0" for a match.
else echo 1; # Print a "1" if no match.
fi;
}
contains "$1" "$2"
여기서 0은 "포함"(참값)을 의미합니다.
이는 다음과 같이 테스트됩니다.
$ contains "test a simple line" simpl
1
$ contains "One sentence" "No more"
0
답변2
Bourne 쉘에는 이러한 목적을 위한 구성이 있습니다. 이것은 현대의 것과 동일합니다 sh
(이것은 Bourne 쉘에서 지원되지 않는 사용 중인 것과 더 비슷해 보입니다 $(...)
. Bourne 쉘인 경우 다른 오류가 발생합니다).
case $1 in
*"$2"*) printf '"%s" is in "%s"\n' "$2" "$1"
esac
을 사용하려는 경우 grep
다음과 같습니다.
if printf '%s\n' "$1" | grep -Fqe "$2"; then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
또는
if grep -Fqe "$2" << EOF
$1
EOF
then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
$2
그러나 개행 문자가 포함되지 않은 경우에만 제대로 작동합니다.
그럼에도 불구하고 대부분의 매개변수 확장을 인용해야 합니다. 필요하지 않은 유일한 곳은 저 위지만 case $1
, 그래도 case "$1"
아프지는 않습니다.
코드에 대한 몇 가지 참고 사항:
echo
임의의 문자열 과 함께 사용할 수 없습니다.. 여기서는 구현에 따라echo
또는 같은 값에 대해서는 실패합니다.$1
-n
foo\bar
- 셸에서 인용되지 않은 매개변수 확장은 매우 특별한 의미를 갖습니다.. 당신은 그렇게하고 싶지 않습니다. 예를 들어,
grep -c $2
또는 같은 값을 사용해 보세요 .$2
*
root /etc/passwd
grep
없이는-F
정규식 일치에 사용됩니다.-F
문자열(하위 문자열) 검색(과거)을 수정 해야fgrep
하지만$2
여러 줄이 포함된 경우 다시grep -F
검색하려는 경우어느입력에서 이러한 줄의 내용은 문자열이 아닌 or 를grep -F $'a\nb'
찾습니다 .a
b
$'a\nb'
- 에서
grep -c $2
로 시작하면 의 내용은$2
옵션으로 처리됩니다-
. 당신은 이 상황을 원grep -c -e "$2"
하거나grep -c -- "$2"
피합니다. - 부울 조건을 보고하기 위해 표준 출력 대신 종료 상태를 사용하려고 합니다. 스크립트에서
exit
(exit 0
true의 경우exit 1
(또는 0이 아닌 숫자, 120보다 큰 값은 피함)의 경우 false)를 사용합니다. 기능의 경우return
대신 사용하세요. 스크립트와 함수 모두 마지막 명령 실행 상태를 반환합니다. $(cmd)
확장하다후행 줄 바꿈을 뺀 출력cmd
(그리고 따옴표가 다시 누락되어 여기에서 분할+glob을 거치는 것)입니다. 따라서cmd
출력이 로 확장0\n
되면 run 은 이라는 명령을 실행하려고 시도합니다 . 출력을 종료 상태로 변환하려면 (부울로 사용할 수 있음) 종료 코드로 출력으로 종료되는 서브셸이 시작됩니다 .$(cmd)
0
$(cmd)
0
cmd
(exit "$(cmd)")
cmd
grep -c
발생 횟수를 계산합니다. 여기에서는 전체 개수가 필요하지 않으며, 검색되었는지(일치하는 항목이 하나 이상 있는지)만 알면 됩니다.grep -q
일단 찾으면 검색을 중지하므로 이것이 더 효율적이기 때문입니다 .grep
(표준) 옵션을 지원하지 않는-q
이전 구현 의 경우 첫 번째 일치에서 중지 되지만 파일 이름을 출력하는fgrep -le "$2" > /dev/null
.for 를 사용할 수 있습니다 (여기에서는 출력을 리디렉션하여 삭제합니다 ).-l
fgrep
/dev/null
답변3
Bash는 기본적으로 이를 지원합니다.
$ string1="abcmoocow"
$ string2="moo"
$ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi
Match
$ string1="abccrowcow"
$ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi
No Match
또한 귀하의 예를 수정하십시오.
if $(echo $1 | grep -c $2) ; then
이 되다:
if [ -n "$(echo $1 | grep -c $2)" ]; then
(grep이 데이터를 반환하는지 확인)
또한 종료 코드도 사용할 수 있습니다.
$ echo bob | grep "o" &>/dev/null; echo $?
0
$ echo bob | grep "z" &>/dev/null; echo $?
1