
원래 문자열은 다음과 같습니다.
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]+)
및 .abc
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
*
를 in 과 같이 사용하면 [0-9]*-[0-9]*
대시 str-str
(주위에 숫자가 0임)와 일치하므로 작동하지 않습니다.
전체 라인을 일치시키고 유지하고 싶은 부분을 캡처해야 한다고 생각한다면 이 작업도 수행할 수 있습니다. 다음 명령은 밑줄을 포함하여 숫자가 아닌 초기 숫자와 마지막 비트를 캡처합니다.
$ sed 's/\([^0-9]*\).*\(_.*\)/\1\2/' file
str-str_01
str-str_05
그러나 이것은 해독하기가 약간 어렵고 질문에서 언급하지 않은 문자열의 시작과 끝을 가정합니다. 예를 들어, 시작 부분에는 제거하려는 숫자 앞에 숫자가 포함될 수 없으며 문자열의 끝은 끝 부분에서 잘립니다.마지막문자열의 해당 부분에 여러 개의 밑줄이 있는 경우 제거하려는 숫자 뒤에 반드시 밑줄이 있어야 하는 것은 아닙니다.
비트만 캡처되지 않도록 항상 이 표현식에 추가할 수 있지만 NNN-NNN
그렇게 하면 표현식을 이해하기가 더욱 어려워집니다.