테이블 이름에 정수가 포함되어 있는지 확인하는 쉘 스크립트에 if 루프가 있습니다. 이것이 제가 지정한 조건입니다.
if [[ "$able_name" == *[0-9]* ]]
일반적으로 테이블 이름은 다음과 같습니다.
tablename_000
또는
tablename_001
하지만 이름이 정규식과 일치하므로 이 루프로 들어가는 새 파일이 있습니다 table_V2
. 이것을 어떻게 피할 수 있습니까? if
밑줄 뒤에 정수가 있고 다른 문자가 없는 경우에만 루프에 들어가야 합니다.
답변1
표준 sh
구문을 사용하십시오.
case ${table_name##*_} in
("$table_name" | "" | *[!0-9]*) echo >&2 incorrect;;
(*) echo correct;;
esac
즉, 검사는 $table_name
맨 오른쪽에 있는 자체(아무것도 의미하지 않음 ) _
도 아니고 빈 문자열도 아니고 숫자가 아닌 문자를 포함하는 모든 것을 제거합니다.$table_name
$table_name
_
문자열을 정규식과 일치시키는 표준 명령 expr
에는 몇 가지 문제가 있으며 코드가 명확하지 않습니다.
if expr " $table_name" : '.*_[0-9]\{1,\}$' > /dev/null; then
echo Correct
else
echo >&2 Incorrect
fi
선행 공백은 $table_name
like +
또는 의 값에 문제가 발생하지 않도록 하기 위한 것입니다 --help
. 정규식은 암시적으로 시작 부분( is .*
)에 고정되지만 끝( is $
)에는 고정되지 않으며 결과(여기서는 0 또는 1)가 종료 상태에 반영되는 것 외에도 stdout에 출력되므로 /로 리디렉션됩니다. 개발/널.
내장 합계 [
와 같은 일부 구현에는 연산자 가 있습니다 (ERE를 사용하지만 다음을 사용 하여 PCRE로 변경할 수 있음).[
zsh
yash
=~
zsh
if [ "$table_name" '=~' '_[0-9]+$' ]; then
echo Correct
else
echo >&2 Incorrect
fi
bash
, 참조의 구문과 동작은 구현마다 다르지만 zsh
그 안에 ksh93
연산자 연산자가 있습니다 . =~
[[...]]
변수를 사용하는 것이 더 좋습니다@BLayer에서 볼 수 있듯이
zsh -o extendedglob
and ksh
( bash -O extglob
또는 zsh -o kshglob
glob 하위 집합 지원 ksh
)에는 구문은 다르지만 기능적으로 정규식과 동일한 glob 연산자가 있습니다.
번역 RE -> ksh-glob/zsh-glob:
[0-9]
->[0-9]
/[0-9]
x+
->+(x)
/x##
$
또는^
-> 암시적/암시적.
->?
.*
->*
(또는*(?)
)/*
(또는?#
)
따라서 ksh
(또는 bash -O extglob
또는 zsh -o kshglob
)에서는:
case $table_name in
(*_+([0-9]) echo correct;;
(*) echo >&2 incorrect;;
esac
존재하다 zsh -o extendedglob
:
case $table_name in
(*_[0-9]##) echo correct;;
(*) echo >&2 incorrect;;
esac
zsh
에서 까지의 십진수를 <x-y>
일치시키는 확장된 glob 연산자 도 있으므로 이를 작성할 수도 있습니다 .x
y
(*_<->) echo correct
=
이러한 쉘에서 이러한 glob은 aka 연산자의 오른쪽에서도 사용할 수 있습니다 ==
[[...]]
.
답변2
아마도 가장 간단한 정규식은 다음과 같습니다.
if [[ "$file" =~ _[0-9]+$ ]]
then
echo OK $file
fi
답변3
이를 수행하는 방법에는 여러 가지가 있습니다. 다음은 전통적인 정규식의 Bash 버전입니다(또는 적어도 Bash가 가지고 있는 것과 가장 가까운 것):
pattern='^tablename_[[:digit:]]+$'
if [[ $filename =~ $pattern ]]; then
echo "Filename $filename is valid"
fi
몇 가지 참고사항:
- 가장 단순한 정규 표현식을 제외한 모든 경우에는 여기에서 사용하는 것처럼 변수를 사용하는 것이 좋습니다
pattern
. 내부 표현식에 단어 분리나 경로 이름 확장이 적용되지 않더라도[[ ]]
물결표, 변수 및 산술 확장과 프로세스 및 명령 대체가 있을 것입니다. 인라인 정규 표현식을 사용하면 부정확하거나 예상치 못한 결과를 얻기 쉽습니다. - POSIX 문자 클래스를 사용하고 있지만
[:digit:]
그것도0-9
괜찮습니다. 여기의 다른 답변 대부분은 후자를 사용한다고 생각하며 완전성을 위해 전자를 보여줄 가치가 있습니다.
댓글: 이 주제에 대한 변형이 너무 많다는 사실(이 스레드에만 있음)은 sh
일부 사람들이 / ...을 좋아하지 않는 이유 중 하나 bash
이며 ... 제가 좋아하는 이유 중 하나입니다.:)
답변4
이를 위해 regex 옵션을 사용하는 것이 좋지만 숫자만 포함하는 일반 glob도 사용할 수 있습니다. 예를 들어 다음과 같은 작업을 수행할 수 있습니다.
for file in tablename_[0-9]*; do
[ -f "$file" ] || continue
printf "%s\n" "$file"
done
에서 정규식 연산자를 사용하면 bash
다음과 같은 작업을 수행할 수 있습니다.
for file in tablename_*; do
if [[ $file =~ _([[:digit:]]+)$ ]]; then
printf "%s\n" "$file"
fi
done