[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 일치 az에서 라틴어가 아닌 악센트 문자 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.