(((
문자열이나 문자열 사이의 단락을 제거하려는 사람이 누구인지 알고 싶습니다.)))
Lorem ipsum (((dolor sat amet))), consectetur adipiscing elit. Vestibulum aliquet fringilla est, dictum tempor nunc venenatis at. sed nec velit sat amet velit cursus imperdiet. Vivamustincidunt ut nunc quis euismod. Quisque sat amet lorem rhoncus, Malesuada justo at, ullamcorpererat.
따라서 "dolor sat amet"이 반환값에 표시되어서는 안 됩니다.
이것이 제가 지금 가지고 있는 명령입니다. 첫 번째 명령을 감지한 (((
다음 중지합니다.
sed -e "/(((/,/)))/d" file.txt
답변1
sed -e :p -e '/(((/!b
' -e :n -e 's/)))/\
/; s/(((.*\n//; tp
$d;N; s//(((/; tn'
이것은 트릭을 수행해야합니다. 그것은 b
탈출 할 것이다(그래서 자동으로 인쇄됨)일치하지 않는 모든 행은 일단 발견되면 해당 시퀀스 (((
의 첫 번째 발생 과 첫 번째 발생 (((
사이의 모든 항목을 제거하려고 시도합니다 )))
. )))
현재 줄에서 후행을 찾을 수 없기 때문에 찾을 수 없는 경우 , N
확장 줄을 가져와서 (((
그 줄과 다음 줄의 시작 부분 사이의 모든 내용을 삭제하고 다시 검색합니다. $
검색 중에 마지막 줄의 끝에 도달 하면 )))
포기합니다. 이렇게 하면 한 번에 한 줄 이상을 버퍼링하지 않게 됩니다. (((
개행 문자를 가져와야 할 때마다 그 뒤의 모든 내용이 삭제되기 때문입니다.
한 줄에서 가능한 한 많은 쌍을 처리해야 하며 (((
)))
두 끝 사이에 있는지 여부는 중요하지 않습니다. 2보다 크고 그 이하의 숫자를 찾습니다.(
)
)
(
일단 발견되면 )))
검색으로 재설정되므로 (((
개행 경계를 넘은 후에도 다음 쌍을 처리하는 데 실패하지 않습니다.
:p
-p
분기 태그를 선언합니다. 스크립트가)))
시퀀스를 개행 문자로 바꿀 수 있는 경우 스크립트는 해당 위치로 분기하고(((
와 사이의 모든 항목을 삭제합니다\n
./(((/!b
b
-away- 패턴 공간에 시퀀스가 남아 있지 않은 경우 자동으로 패턴 공간을 인쇄합니다 .(((
:n
- 분기:
태그를 선언합니다n
.(((
a가 발견되었지만 같은)))
줄에서 a가 발견되지 않으면 스크립트가 여기에서 분기됩니다.s/)))/\n/
)))
- 개행 문자를 처음 나타나는 문자로 바꿉니다 .(((
이는 a가 이미 일치하는 경우 에만 발생합니다.s/(((.*\n//
(((
- 패턴 공간의 첫 번째 줄과 유일한 줄 사이의 모든 내용을 바꿉니다 .\n
tp
-성공적인 교체가 예상됩니다t
. true인 경우 label 로 분기됩니다:p
.$d;N
- 마지막 대체가 실패했습니다. 현재 행이$
마지막d
요소인 경우, 그렇지 않으면N
패턴 공간에 ext를 추가합니다.s//(((/;tn
- 마지막 정규식을 반복하고(((
첫 번째 항목과 방금 추가한 줄 바꿈 사이의 모든 항목을 바꾼(((
다음 label 로 분기합니다:n
.
답변2
단일 줄 문자열로 이 작업을 수행하는 것은 매우 간단합니다.
sed 's/((([^)]*)))//g' file
여러 줄 문자열을 처리하는 데 필요한 경우 더 복잡해집니다. 한 가지 방법은 모든 줄 바꿈을 tr
널 문자( ) 로 바꾸고 \0
대체를 수행한 후 다시 번역하는 것입니다.
tr '\n' '\0' < file | sed 's/((([^)]*)))//g' | tr '\0' '\n'
아니면 다음을 사용할 수도 있습니다 perl
.
perl -0pe 's/\(\(\([^)]+\)\)\)//g;' file
-0
perl
전체 파일을 메모리로 읽어들이 는 이유(대용량 파일의 경우 문제가 될 수 있음)는 " -p
모든 줄을 인쇄한다"는 의미이지만 -0
, 이후 "줄"은 실제로 전체 파일입니다. 와 s///
같은 생각 입니다 sed
.
답변3
노력하다
sed 's/((([^)]*)))//' file
아니면 당신의 문장이 더 좋을 수도 있습니다
sed 's/ ((([^)]*)))//' file