문자열에 하위 문자열이 포함되어 있는지 테스트


40

코드가 있습니다

file="JetConst_reco_allconst_4j2t.png"
if [[ $file == *_gen_* ]];
then
    echo "True"
else
    echo "False"
fi

file"gen"이 포함되어 있는지 테스트합니다 . 출력은 "False"입니다. 좋은!

문제는 "gen"을 변수로 대체 할 때입니다 testseq.

file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file == *_$testseq_* ]];
then
    echo "True"
else
    echo "False"
fi

이제 출력은 "True"입니다. 어떻게 이럴 수가있어? 문제를 해결하는 방법?


답변:


25

$testseq다음 방법 중 하나로 변수 를 보간해야합니다 .

  • $file == *_"$testseq"_*(여기서는 $testseq고정 문자열로 간주 됨)

  • $file == *_${testseq}_*(여기서 $testseq패턴으로 간주).

또는 _변수 이름 바로 다음에 변수 이름의 일부로 사용됩니다 (변수 이름에 유효한 문자 임).


OP에 적용되지만 이식성이없는 정답입니다. (이것은 제공된 답변에 대한 비판이 아니며 독자에게 경고 일뿐입니다). ;-)
Cbhihe

28

=~연산자를 사용하여 정규식 비교를 수행 하십시오 .

#!/bin/bash
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"
if [[ $file =~ $testseq ]];
then
    echo "True"
else
    echo "False"
fi

이런 식으로 내용 $file이 있는지 비교합니다 $testseq.

user@host:~$ ./string.sh
False

내가 변경하면 testseq="Const":

user@host:~$ ./string.sh
True

그러나, 당신이 공급 $testseq하는 것에주의하십시오 . 그 문자열이 어떻게 든 정규 표현식을 나타내는 경우 (예 [0-9]를 들어) "일치"를 유발할 가능성이 더 큽니다 .

참고 :


20
file="JetConst_reco_allconst_4j2t.png"
testseq="gen"

case "$file" in
    *_"$testseq"_*) echo 'True'  ;;
    *)              echo 'False'
esac

사용 case ... esac은 이식 가능한 방식으로 패턴 일치를 수행하는 가장 간단한 방법 중 하나입니다. 그것은 다른 언어의 "스위치"문으로 작동 ( bash, zsh, 그리고 ksh93또한 당신이 수행 할 수 있습니다 가을-을 통해 다양한 호환되지 않는 방식으로). 사용되는 패턴은 표준 파일 이름 글 로빙 패턴입니다.

문제 _는 변수 이름에 유효한 문자 이기 때문에 발생합니다 . 따라서 쉘은 *_$testseq_*" 와 *_변수의 값 과"이 뒤 따릅니다 . 변수 가 정의되지 않았으므로 빈 문자열로 확장되고 결국 에는 값이 일치하는로 끝나게됩니다 . 파일 이름에 적어도 하나의 밑줄이 포함되어 있으면 얻을 수 있습니다 .$testseq_*$testseq_*_*$fileTrue$file

변수의 이름을 올바르게 구분하려면 다음과 "..."같이 확장을 사용하십시오 *_"$testseq"_*. 변수의 값을 문자열로 사용합니다. 변수 값을 pattern 으로 사용하려면 *_${testseq}_*대신 사용하십시오.

또 다른 빠른 수정은 다음 값에 밑줄을 포함시키는 것입니다 $testseq.

testseq="_gen_"

그런 다음 *"$testseq"*패턴으로 사용 하십시오 (문자열 비교 용).


따라서 쉘은 변수 $ testseq_를 찾고 그것을 찾지 않고 빈 문자열로 대체합니다.
Viesturs

@Viesturs 그게 문제의 핵심입니다.
Kusalananda

1
문자열의 경우 그것이 있어야 검색 *"$testseq"*을위한 case등에 [[...]](zsh을위한 활성화하지 않는 한 제외 globsubst)
스테판 Chazelas가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.