이것은 처음으로 bash 스크립팅이므로 쉽게 실수 할 수 있습니다.
기본적으로 사용자 그룹을 가져 오는 스크립트를 작성하려고하는데 특정 그룹에 있으면 그에 따라 기록합니다. 분명히 더 많은 기능이있을 것이지만 정규식을 작동시킬 수 없을 때도 포인트가 없습니다!
지금까지 나는 이것을 가지고있다 :
#!/bin/bash
regex="^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
# example output
groups="username : username usergroup"
echo "$groups" >> /home/jrdn/log
if [[ "$groups" =~ $regex ]]; then
echo "Match!" >> /home/jrdn/log
else
echo "No match" >> /home/jrdn/log
fi
정규식을 시도한 모든 곳에서 작동합니다. 하지만 bash는 스크립트에서, 그것은 단지 이제까지 출력 $groups
, 다음을 No match
. 그래서 누군가가 무엇이 잘못되었는지 말해 줄 수 있습니까?
답변
보낸 사람 man 7 regex
:
대괄호 표현식은 “[]”로 묶인 문자 목록입니다. …
… 문자 ‘-‘를 포함 시키려면 첫 문자 또는 마지막 문자로 만드십시오.… [A] ‘\’를 포함한 다른 특수 문자는 대괄호 표현식 내에서 특별한 의미를 잃습니다.
egrep으로 정규 표현식을 시도하면 오류가 발생합니다.
$ echo "username : username usergroup" | egrep "^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
egrep: Invalid range end
다음은 더 간단한 버전이며 오류가 발생합니다.
$ echo 'hi' | egrep '[\-_]'
egrep: Invalid range end
\
특별한 것이 아니기 때문에 , 그것은 범위와 같습니다 [a-z]
. 또는 다음 -
과 같이 마지막 에 넣어야합니다 [_-]
.
echo "username : username usergroup" | egrep "^([a-zA-Z0-9_-]+ : [a-zA-Z0-9_-]+) (usergroup)$"
username : username usergroup
이것은 libc 버전과 상관없이 작동해야합니다 (egrep 또는 bash).
편집 : 이것은 실제로 로케일 설정에 달려 있습니다. 맨 페이지에서 이에 대해 경고합니다.
범위는 배열 순서에 따라 매우 다르며 이식 가능한 프로그램은 범위에 의존하지 않아야합니다.
예를 들면 다음과 같습니다.
$ echo '\_' | LC_ALL=en_US.UTF8 egrep '[\-_]'
egrep: Invalid range end
$ echo '\_' | LC_ALL=C egrep '[\-_]'
\_
물론 오류가 발생하지 않았지만 원하는 것을 수행하지 않습니다.
$ echo '\^_' | LC_ALL=C egrep '^[\-_]+$'
\^_
그것은 ASCII에 포함하는 범위의 \
, [
, ^
,와 _
.
답변
정규 표현식 (및 더 큰 코드 조각의 모든 버그)이있는 일반적인 규칙 : 단계별로 자르고 다시 작성하거나 이등분을 사용하십시오.
이 경우 범인은 밑줄로 밝혀졌습니다. 백 슬래시로 이스케이프 처리하면 효과가 있습니다.