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


13

현재 경로에 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)

2
정규 표현식과 glob의 차이점에 대한 자세한 내용은 이 질문 을 참조하십시오 .
— terdon

4
a_*_data이 파일들과 일치 하는 사실 이 당신을 놀라게하지 않았습니까?
— Cthulhu

@Cthulhu 당신이 나를 얻었다!
— user13107

답변:


29

이 [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

bash 정규식을 사용하는 방법? ( tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html 참조 )
— user13107


21

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

이것은 네 부분 으로 나눌 수 있습니다 .

  • a_의 시작과 일치 a_clean_0db_data떠나, clean_0db_data일치하는

  • [a-z]범위의 임의의 문자와 일치하는 a-z(예를 c떠나) lean_0db_data일치시킬

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

  • _data 후행과 일치 _data

정규 표현식에서 a..z 범위의 모든 문자 (0 포함)를[a-z]* 의미 하지만 정규 표현식이 아닌 쉘 글 로빙을 처리합니다.

정규식을 원하면 몇 가지 find구현에 다음과 같은 -regex조건이 있습니다.

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

은 -maxdepth당신이.에있는 폴더로 검색 결과를 제한 할 경우에만 여기에 정규 표현식이 일치하는 전체 , 파일 이름을 따라서 난을 추가 한 ^.*/경로-부분을 일치


11

*쉘 패턴에서 0 개 이상의 문자와 일치합니다. 0 이상의 선행 atom* 을 의미하는 정규식 연산자 와 혼동해서는 안됩니다 .

*기본 쉘 패턴 에는 정규 표현식 에 해당하지 않습니다 . 그러나 다양한 쉘에는 확장 기능이 있습니다.

  • ksh있다 *(something):

    ls a_*([a-z])_data
  • bash와 함께 shopt -s extglob또는 zsh함께 사용할 수 있습니다 setopt kshglob:

    shopt -s extglob
    ls a_*([a-z])_data
  • 에서 zsh함께 extendedglob사용할 수, #정규 표현식에 해당합니다 *:

    setopt extendedglob
    ls a_[a-z]#_data
  • 의 최신 버전에서는 ksh93glob에서 정규 표현식을 사용할 수도 있습니다. 여기에 확장 된 정규 표현식 :

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

참고 [a-z]현재 지역에 따라 다른 일을 일치합니다. 그것은 일반적으로 단지 26 일치 a에 z에서 라틴어가 아닌 악센트 문자 C로케일을. 다른 로케일에서는 일반적으로 더 많이 일치하며 항상 의미가있는 것은 아닙니다. 로케일의 문자를 찾으려면을 (를) 선호 할 수 있습니다 [[:alpha:]].


[a-z]C 로케일에서 26자가 일치하는 것보다 더 일치 하는 예를들 수 있습니까? 내가 마지막으로 이것을 보았을 때 기억하는 것, Unix 변형에서 실제로 사용되는 모든 인코딩은 ISO-646을 기본으로 사용했습니다 (따라서 다르게 사용되는 상위 128 코드는 ISO-8859-X와 같은 인코딩의 문자에 대해 직접 UTF-8 또는 EUC 제품군과 같은 인코딩). AIX조차도 EBCDIC 로케일을 가지고 있지 않았습니다 (적어도 나에게 가능한 한). POSIX / UNIX 표준이 요구 한 경우를 찾은 것을 기억하지만 결과는 기억 나지 않습니다.
— AProgrammer

1
@AProgrammer는 인코딩과 독립적이며 정렬 순서 (LC_COLLATE)를 기반으로합니다. [a-z]일반적으로 포함 é하거나 í(그러나 반드시 ź그 인코딩 코드 포인트가 그와 Z 사이 아닌지 여부를 상기 캐릭터이를 갖는 로케일에서)한다. C 로케일 만 코드 포인트 값을 기준으로 정렬 순서를 보장합니다. 자세한 내용은 이 다른 답변 을 참조하십시오.
— Stéphane Chazelas

좋아, 내가 놓친 것은 범위가 현재 데이터 정렬 순서에 따라 해석되었다는 것입니다.
— AProgrammer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.