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

코드 있음

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”입니다. 어떻게 그럴수있어? 문제를 해결하는 방법은 무엇입니까?

설명

Answer

변수는 다음 방법 중 하나입니다.

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

  • $file == *_${testseq}_* (여기서는 $testseq는 패턴).

또는 변수 이름 바로 뒤의 _는 변수의 일부로 간주됩니다. 이름 ( “변수 이름의 유효한 문자).

코멘트

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

답변

=~ 연산자 사용 또는 정규식 비교 :

#!/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]) “일치”를 트리거 할 가능성이 더 높습니다.

참조 :

댓글

  • " bash " 만

답변

file="JetConst_reco_allconst_4j2t.png" testseq="gen" case "$file" in *_"$testseq"_*) echo "True" ;; *) echo "False" esac 

case ... esac를 사용하는 것은 이식 가능한 방식으로 패턴 일치를 수행하는 가장 간단한 방법 중 하나입니다. 다른 언어 (bash, zshksh93을 사용하면 호환되지 않는 다양한 방식으로 폴 스루 를 수행 할 수 있습니다. 사용 된 패턴은 표준 파일 이름 globbing 패턴입니다.

문제는 _가 변수 이름의 유효한 문자이기 때문입니다. 따라서 셸은 *_$testseq_*를 “*_로 표시하고 그 뒤에 변수 $testseq_를 표시합니다. 및 * “입니다. $testseq_ 변수는 정의되지 않았으므로 빈 문자열로 확장되며 *_*로 끝납니다. div id = “db3c2b02d3″>

값입니다. $file의 파일 이름에 밑줄이 하나 이상 포함되어 있으면 True를 얻을 수 있습니다.

올바르게하려면 변수 이름을 구분하고 확장 주위에 "..."를 사용합니다 : *_"$testseq"_*. 이것은 변수의 값을 문자열로 사용합니다. 변수 값을 패턴 으로 사용하려면 대신 *_${testseq}_*를 사용하세요.

또 다른 빠른 수정은 다음을 포함하는 것입니다. $testseq 값의 밑줄 :

testseq="_gen_" 

그런 다음 *"$testseq"*를 패턴으로 사용합니다 (문자열 비교 용).

주석

  • 따라서 쉘은 변수 $ testseq_를 찾고 찾지 못합니다. 빈 문자열로 대체합니다.
  • @Viesturs '가 문제의 핵심입니다.
  • 하위 문자열 검색은 case의 경우 *"$testseq"* 여야합니다 ([[...]]의 경우처럼 globsubst 사용)
  • [ "${str##*substr*}" ] || echo True보다 간단합니까?
  • @Isaac 무엇을 읽고 이해하는 측면에서 ' s 일어나고 있습니다. 또한 ' " if-then-elif-then-elif

스파게티. 단일 문자열을 테스트하더라도 (대체에서 문자열이 사라지는 지 여부) 표시되는 방식은 더 짧습니다.

Answer

문자열에 하위 문자열이 포함되어 있는지 테스트하는 이식 가능한 방법은 다음을 사용하십시오.

file="JetConst_reco_allconst_4j2t.png"; testseq="gen" [ "${file##*$testseq*}" ] || echo True Substring is present 

또는 "${file##*"$testseq"*}"testseq에서 glob 문자를 해석하지 않도록합니다.

댓글

  • ' ["와 같은 항목이 필요합니다. $ {file ## * $ testseq *} "! = " $ file " ] 대시에서 가장 큰 접두사 패턴 제거이기 때문입니다.
  • 아니요, @NoelGrandin 대부분의 셸 (대시 포함)에 변경 사항이 없으므로 가장 큰 접두사 패턴 이 전체 문자열이됩니다. 변수 하위 패턴 ($testseq) 값이 $file 값에 포함 된 경우. 시도 : dash -c 'file="JetConst_reco_allconst_4j2t.png"; testseq="reco"; echo "=${file##*"$testseq"*}="' 대시가 전체 문자열을 제거하는지 확인합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다