Bash 스크립트의 정규식

Bash 스크립트의 정규식

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

정규식(및 더 큰 조각의 버그)에 대한 일반 규칙: 단계별로 잘라내고 다시 작성하거나 이분법을 사용하세요. 둘 중 더 나은 방법을 사용하세요.

이 경우 범인은 밑줄로 밝혀졌습니다. 백슬래시를 사용하여 이스케이프 처리하면 됩니다.

관련 정보