[az] 별표가 숫자와 일치하는 이유는 무엇입니까?

[az] 별표가 숫자와 일치하는 이유는 무엇입니까?

현재 경로에는 3개의 디렉터리가 있습니다.

$ls
a_0db_data  a_clean_0db_data  a_clean_data
$ls a_*_data
a_0db_data:

a_clean_0db_data:

a_clean_data:

$ls a_[a-z]*_data
a_clean_0db_data:

a_clean_data:

마지막 ls 명령은 에만 일치할 것으로 예상했습니다 a_clean_data. 왜 포함된 명령과도 일치합니까 0?

bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

답변1

부품이 [a-z]숫자와 일치하지 않습니다. 이것은 *쉘에 대해 혼란스러울 수 있습니다.와일드카드그리고일반적인 표현.

grep다양한 종류의 정규식을 허용하는 도구(기초적인기본적으로 -E확장의 -P경우펄 정규식)

예를 들어 ( -v역 일치)

$ ls a_[a-z]*_data | grep -v "[0-9]"
a_clean_data

bash 정규식을 사용하려는 경우 $ref변수가 정수인지 테스트하는 방법에 대한 예는 다음과 같습니다.

re='^[0-9]+$'
if ! [[ $ref =~ $re ]] ; then
  echo "error"
fi

답변2

그래서 질문은: 왜 a_[a-z]*_data일치합니까 a_clean_0db_data?

이는 다음과 같이 나눌 수 있습니다.4개부분:

  • a_경기 시작 a_clean_0db_data, clean_0db_data매칭을 위해 떠난다

  • [a-z]범위 내 모든 문자 a-z(예: c) 와 일치하며 lean_0db_data일치하도록 남겨둡니다.

  • *임의 개수의 문자와 일치합니다.lean_0db

  • _data후행 일치_data

정규식에서는 [a-z]*다음을 의미합니다 .a..z 범위의 임의 개수의 문자(0 포함), 그러나 정규 표현식이 아닌 쉘 와일드카드를 다루고 있습니다.

정규식이 필요한 경우 일부 find구현에는 -regex조건자가 있습니다.

find . -maxdepth 1 -regex "^.*/a_[a-z]*_data$"

이렇게 하면 -maxdepth검색 결과가 현재 있는 폴더로만 제한됩니다.정규식성냥모두^.*/파일 이름이므로 경로 부분과 일치하도록 추가했습니다.

답변3

*쉘 패턴에서 0개 이상의 문자와 일치합니다. *정규식 연산자 와 혼동하지 마십시오 .0개 이상의 선행 원자.

*기본 쉘 모드에는 regexp와 동등한 것이 없습니다. 그러나 다양한 쉘에는 이에 대한 확장 기능이 있습니다.

  • ksh가지다 *(something):

    ls a_*([a-z])_data
    
  • bashshopt -s extglob다음과 함께 또는 에서 zsh동일한 콘텐츠를 가질 수 있습니다 setopt kshglob.

    shopt -s extglob
    ls a_*([a-z])_data
    
  • 활성화 zsh되면 regexp와 동일 extendedglob합니다 .#*

    setopt extendedglob
    ls a_[a-z]#_data
    
  • 최신 버전에서는 ksh93glob에서 정규식을 사용할 수도 있습니다. 이것과 함께확장하다일반적인 표현:

    ls ~(E:a_[a-z]*_data)
    

[a-z]현재 로케일에 따라 다른 콘텐츠가 일치됩니다 . 일반적으로 로케일에서 a최대 26개의 z악센트가 없는 라틴 문자 만 일치합니다 C. 다른 로케일에서는 일반적으로 더 많이 일치하지만 항상 의미가 있는 것은 아닙니다. 해당 로케일의 문자를 일치시키려면 를 선호할 수 있습니다 [[:alpha:]].

관련 정보