숫자 앞과 밑줄 뒤의 문자열 추출

숫자 앞과 밑줄 뒤의 문자열 추출

원래 문자열은 다음과 같습니다.

str-str001-002_01
str-str005-006_05

숫자 앞과 밑줄 뒤의 문자열을 추출하고 싶습니다. 다음과 같습니다.

str-str_01
str-str_05

sed가 패턴을 다음과 같은 그룹으로 분리할 수 있었던 것으로 기억합니다.

 sed -n 's/\(^.*\)\([0-9]-[0-9]\)\(.*$\)/\1\3/p'

하지만 다음과 같이 인쇄됩니다.

str-str0002_01

그러다가 [0-9]가 하나의 숫자인 것을 기억해서 + 기호나 * 기호로 시도해 보았습니다. 그런 다음 빈 결과를 제공합니다.

추신 : 사용하여

echo 'str-str001-002_01' | sed -n 's/\(^.*\)\([0-9]-[0-9]\)\(.*$\)/\2/p'

일치한다고 볼 수 있습니다 1-0.

그런 다음 다음과 같이 시도했습니다.

echo 'str-str001-002_01' | sed -n 's/\(^.*\)\([0-9]\+-[0-9]\+\)\(.*$\)/\2/p'

처음 2개의 숫자만 남았고 일치하는 숫자만 남았습니다.

1-002

그럼 어떻게 일치시키나요?001-002

답변1

이는 필요한 출력을 제공합니다.

sed -nE 's/^([^0-9]*).*_([^_]+)$/\1_\2/p'

귀하의 예에서 출력

str-str_01
str-str_05

설명

  • sed -nE 's/…/…/p'- ERE를 사용하고, 일치하지 않는 한 줄을 인쇄하지 마세요.
  • ^- 줄의 시작 부분에 앵커
  • ([^0-9]*)- 가능한 한 긴 패턴, 즉 숫자가 아닌 문자가 하나 이상 일치합니다.
  • .*_- 가능한 한 많이 일치하고(아무 것도 포함하지 않음) " _" 가 뒤에 옵니다.
  • ([^_]+)- 밑줄이 아닌 가능한 한 긴 패턴(최소 한 문자)과 일치합니다.
  • $- 줄 끝 부분에 앵커
  • \1_\2- 전체 줄을 첫 번째 (…)일치 항목 " _" 및 두 번째 (…)일치 항목 으로 바꿉니다.

시도가 예상대로 작동하지 않은 이유는 *(및 +)이 탐욕스럽기 때문입니다. 이전 원자와 일치하는 가능한 한 많은 문자를 소비합니다. 따라서 (.*)([0-9]+)와 같은 것에 적용된 ERE의 경우 abc123.* 소비하고 일치하도록 abc12남겨둡니다 . "가 필요합니다.[0-9]+3숫자가 아닌" 첫 번째 일치를 제한하려면: ([^0-9]*)([0-9]+)및 .abc123

답변2

$ cat file
str-str001-002_01
str-str005-006_05
$ sed 's/[0-9]\{3\}-[0-9]\{3\}//' file
str-str_01
str-str_05

여기서 대체 명령은 세 자리 숫자가 일치하는 NNN-NNN위치를 일치시키고 제거하는 것입니다.NNN

일치시키다적어도 하나숫자, 1,다음 대신 사용 3:

$ sed 's/[0-9]\{1,\}-[0-9]\{1,\}//' file
str-str_01
str-str_05

+이는 확장 정규식에서 사용하는 것과 같습니다 . 기본적으로 사용되는 정규식 sed은 "기본" 정규식이며 +리터럴 더하기 문자와 일치합니다. 대부분의 sed구현은 다음을 사용하여 확장 표현식도 지원합니다 -E.

$ sed -E 's/[0-9]+-[0-9]+//' file
str-str_01
str-str_05

*를 in 과 같이 사용하면 [0-9]*-[0-9]*대시 str-str(주위에 숫자가 0임)와 일치하므로 작동하지 않습니다.


전체 라인을 일치시키고 유지하고 싶은 부분을 캡처해야 한다고 생각한다면 이 작업도 수행할 수 있습니다. 다음 명령은 밑줄을 포함하여 숫자가 아닌 초기 숫자와 마지막 비트를 캡처합니다.

$ sed 's/\([^0-9]*\).*\(_.*\)/\1\2/' file
str-str_01
str-str_05

그러나 이것은 해독하기가 약간 어렵고 질문에서 언급하지 않은 문자열의 시작과 끝을 가정합니다. 예를 들어, 시작 부분에는 제거하려는 숫자 앞에 숫자가 포함될 수 없으며 문자열의 끝은 끝 부분에서 잘립니다.마지막문자열의 해당 부분에 여러 개의 밑줄이 있는 경우 제거하려는 숫자 뒤에 반드시 밑줄이 있어야 하는 것은 아닙니다.

비트만 캡처되지 않도록 항상 이 표현식에 추가할 수 있지만 NNN-NNN그렇게 하면 표현식을 이해하기가 더욱 어려워집니다.

관련 정보