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

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

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

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에 적용된 ERE 의 경우 소모되어 매치가 남게 abc123됩니다 . "가 필요합니다..*abc12[0-9]+3숫자가 아님" 첫 번째 일치로 제한: ([^0-9]*)([0-9]+)get abcsum 123.

답변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

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


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

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

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

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

관련 정보