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
. 그러면 무슨 일이 일어나고 있는지 말해 줄 수 있는 사람이 있습니까?
답변1
에서 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로 \
, [
, ^
를 포함하는 범위입니다 _
.
답변2
정규식(및 더 큰 조각의 버그)에 대한 일반 규칙: 단계별로 잘라내고 다시 작성하거나 이분법을 사용하세요. 둘 중 더 나은 방법을 사용하세요.
이 경우 범인은 밑줄로 밝혀졌습니다. 백슬래시를 사용하여 이스케이프 처리하면 됩니다.