코드 있음
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
, zsh
및 ksh93
을 사용하면 호환되지 않는 다양한 방식으로 폴 스루 를 수행 할 수 있습니다. 사용 된 패턴은 표준 파일 이름 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"*}="'
대시가 전체 문자열을 제거하는지 확인합니다.