%와 그 바로 뒤에 오는 숫자를 제외하고 문자열의 모든 것을 sed로 어떻게 대체할 수 있나요? 즉, 다음과 같은 문자열을 제외한 모든 것:
%1
%1000
%55
등.
다음 형식의 문자열이 제공됩니다.
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
%3
나는 및 부분 만 얻고 싶습니다 %4
. 숫자는 까지 올라갈 수 있습니다 999
.
답변1
$ sed 's/^.*\(%[0-9]\+\).*$/\1/' input
한 줄에 최대 하나의 %123
토큰이 포함되어 있고 모든 줄에 그러한 토큰이 포함되어 있다고 가정합니다.
메타 \( \)
문자는 일치 그룹을 표시하며 이는 역 \1
참조를 통해 대체에서 참조됩니다. ^
/ $
줄의 시작/끝과 일치합니다.
그렇지 않으면 입력을 사전 필터링할 수 있습니다. 예:
$ grep '%[0-9]\+' input | sed 's/^.*\(%[0-9]\+\).*$/\1/'
(모든 줄에 그러한 토큰이 포함되어 있지 않은 경우)
또 다른 변형:
$ sed 's/\(%[0-9]\+\)/\n\1\n/g' | grep '%[0-9]'
(라인에 해당 토큰이 여러 개 포함될 수 있는 경우)
다음은 파이프의 첫 번째 부분에서 각 토큰 바로 앞과 뒤에 삽입된 줄 바꿈입니다. 그런 다음 grep
부품은 토큰이 아닌 모든 %123
라인을 제거합니다.
답변2
grep -o
이 경우 다음을 사용하는 것이 더 나을 수 있습니다 .
grep -oP '\B%[0-9]{1,3}\b' inputfile
사용 중인 버전이 grep
Perl 호환 정규 표현식( -P
)을 지원한다고 가정합니다. 그렇지 않으면:
grep -o '\B%[0-9]\{1,3\}\b' inputfile
GNU를 사용하면 sed
공백을 줄 바꿈으로 음역하여 원하는 줄을 얻을 수 있습니다.
sed 'y/ /\n/' inputfile | sed '/^%[0-9]\{1,\}/!d'
답변3
작업할 때 sed
거의 항상 다음을 수행하는 것이 좋습니다.
/address then/s/earch/replace/
여기에는 두 가지 이유가 있습니다. 첫 번째는 여러 줄을 사용하는 것이 /addressing/
더 빠르다는 것입니다.찾다일치하며 편집을 위해 줄의 일부만 선택하지 않아도 되므로 결과 범위를 더 빨리 좁힐 수 있습니다.
두 번째 이유는 동일한 주소에서 여러 편집 작업을 수행할 수 있기 때문에 작업이 훨씬 쉬워집니다.
물론 이 경우에는 표시한 데이터만 고려하면 실제적인 차이는 없습니다. 그래도 질문하신 내용은 다음과 같습니다.
sed '/^[^%]*\|[^0-9]*$/s///g' <<\DATA
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
DATA
#OUTPUT
%3
%4
단지 다음과 같은 모든 문자를 선택합니다.비%줄 시작 부분의 문자와 모든 문자숫자가 아닌주소의 줄 끝에서 문자를 제거한 다음 s///
-로 제거하면 그게 전부입니다.
현재 형식에서는 줄을 입력하면 예상치 못한 방식으로 데이터가 엉망이 될 수 있습니다.~ 아니다콤보가 포함되어 있으므로 %digit
주소 지정이 중요합니다. 조금 변경하면 다음과 같습니다.
/%[0-9]/s/[^%]*\|[^0-9]*$//g
더 안전해진다그리고더 빠르게.
답변4
내 솔루션은 sed를 사용하지 않고 확장 정규식 및 일치하는 옵션만 사용하는 grep을 사용합니다.
$ cat file
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
$ cat file | grep -Eo '%[0-9]+'
%3
%4
이 경우 grep을 사용하는 것은 sed를 사용하는 것보다 간단합니다.