문자열의 모든 내용(% 및 바로 뒤에 오는 숫자 제외)을 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를 사용하는 것보다 간단합니다.