Sed와 캡처 그룹과의 전투

Sed와 캡처 그룹과의 전투

아래와 같은 텍스트 파일이 있습니다.

(111)1111111
(111)-111-1111
(111)111-1111
111.111.1111

정규식과 sed를 사용하여 그룹 캡처를 연습하는 데 사용합니다. 파일에 대해 실행하는 명령(test라고 함)은 다음과 같습니다.

sed 's/(?\(\d(3}\)[-.]?\(\d{3}\)[-.]?\(\d{4}\)/\1\2\3' test > output

예상되는 출력은 각 줄의 모두 1입니다. 그러나 내가 얻는 것은 변경 사항이 없는 전체 파일뿐입니다. 무엇이 잘못되었나요?

답변1

표준 기본 정규식에서 (?\(\d(3}\)[-.]?이는 다음을 의미합니다.

a literal left parenthesis
a literal question mark
(start of a group)
a literal character 'd'
a literal left parenthesis 
the number '3'
a literal closing brace
(end of group)
a dash or a dot
a question mark

즉, 다음과 같이 인쇄됩니다 x.

echo '(?d(3}-?' |sed 's/(?\(\d(3}\)[-.]?/x/'

sed -EERE(확장 정규 표현식)를 활성화한 다음 그룹화 및 리터럴 괄호로 묶기 위해 (및 를 사용할 가능성이 높습니다 .)\(\)

또한 이것은 \d표준 정규식이 아닌 Perl 정규식의 일부이며 GNU sed는 일부 이스케이프를 지원하지만 표준은 아닙니다(내 생각에는 그렇지 않습니다). 마찬가지로 GNU sed는 ERE의 의미를 표현하기 위해 BRE에서 이를 지원하지만 이는 표준이 아닙니다.\X\d\??

이 모든 것을 염두에 두고:

$ echo '(123)-456-7890' | sed -E 's/\(?([0-9]{3})\)?[-.]?([0-9]{3})[-.]?([0-9]{4})/\1\2\3/'
1234567890

무차별 대입으로 숫자를 제외한 모든 항목을 제거할 수도 있습니다.

$ echo '(123)-456-7890' | sed -e 's/[^0-9]//g'
1234567890

(물론 다음과 (123)-4.5-6-7a8b9c0같은 것도 허용됩니다...)

또한보십시오:

답변2

awk 명령으로도 할 수 있습니다

echo "123-45-6789-10101"| awk '{gsub("[^0-9]","",$1);print }'

산출

12345678910101

답변3

이르카초에 대한 설명정규식이 작동하지 않는 이유가 좋습니다 sed(지원되지 않는 방언입니다).

존재하지 않는 문자만 제거하는 또 다른 접근 방식은 다음과 같습니다 1.

sed 's/[^1]//g' file

그룹을 사용하려면 다음과 같이 할 수 있습니다.

sed -E 's/([^1]*)(1+)([^1]*)/\2/g' file

즉, 양쪽에서 비어 있을 수 있는 1이 아닌 문자열로 구분된 비어 있지 않은 1 문자열을 일치시키고 모든 것을 일치하는 1 문자열로 바꿉니다.

모든 숫자를 처리하려면 과 로 변경 1하세요 .[0-9][^1][^0-9]

관련 정보