텍스트 파일에서 지정된 두 문자열 사이의 모든 텍스트를 제거해야 합니다. 문자열은 다른 줄에 있을 수 있습니다. 예를 들어 다음 텍스트 파일에서
@article{ginsberg_lifespan_2018,
title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
abstract = {test1
test2 abstract {NS}
test3},
language = {en},
urldate = {2018-12-05},
author = {Ginsberg, Daniel},
month = dec,
year = {2018}
}
@article{higaki_two-dimensional_2017,
title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
abstract = {We study the two-dimensional stationary Navier-Stokes equations with rotating effect in the whole space. The unique existence and the asymptotics of solutions are obtained without the smallness assumption on the rotation parameter.},
journal = {arXiv:1703.07372 [math]},
author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
month = mar,
year = {2017},
note = {arXiv: 1703.07372},
keywords = {Mathematics - Analysis of PDEs}
}
이 문자열을 포함하여 항상 줄 끝에 있는 abstract =
와 a 사이의 모든 항목을 제거하고 싶습니다 . },
즉, 다음과 같은 출력을 원합니다.
@article{ginsberg_lifespan_2018,
title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
language = {en},
urldate = {2018-12-05},
author = {Ginsberg, Daniel},
month = dec,
year = {2018}
}
@article{higaki_two-dimensional_2017,
title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
journal = {arXiv:1703.07372 [math]},
author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
month = mar,
year = {2017},
note = {arXiv: 1703.07372},
keywords = {Mathematics - Analysis of PDEs}
}
이런 유형의 질문이 있다는 것을 알고 게시된 솔루션을 시도해 보았습니다. 예를 들어, 나는
perl -0777 -pe 's/abstract = .*},\n/\n/gs'
abstract =
그러나 이렇게 하면 연속되는 항목이 아닌 첫 번째 항목과 마지막 항목 사이의 텍스트가 제거됩니다 },
. 이게 내가 얻은 거야
@article{ginsberg_lifespan_2018,
title = {On the lifespan of three-dimensional gravity water waves with vorticity},
keywords = {Mathematics - Analysis of PDEs}
}
원하는 결과를 얻으려면 이 명령을 어떻게 수정해야 합니까?
답변1
$ sed '/abstract = .*},$/d; /abstract = /,/},$/d' <file
@article{ginsberg_lifespan_2018,
title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
language = {en},
urldate = {2018-12-05},
author = {Ginsberg, Daniel},
month = dec,
year = {2018}
}
@article{higaki_two-dimensional_2017,
title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
journal = {arXiv:1703.07372 [math]},
author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
month = mar,
year = {2017},
note = {arXiv: 1703.07372},
keywords = {Mathematics - Analysis of PDEs}
}
먼저 전체 한 줄 abstract
항목을 제거하려고 시도하고, 그래도 작동하지 않으면 여러 줄 항목을 제거하려고 시도합니다 abstract
. 여러 줄 항목은 abstract =
포함 줄부터 로 끝나는 다음 줄까지의 줄 집합 입니다 },
.
주석이 달린 sed
스크립트:
/abstract = .*},$/d # delete complete abstract line, skip to next input line
/abstract = /,/},$/d # delete multi-line abstract entry
예를 들어 시작 문자열을 더 구체적으로 지정해야 하는 경우 이러한 표현식의 일부를 ^[[:blank:]]*abstract
대신 사용할 수 있습니다. 이 줄 앞에는 공백이나 탭만 abstract
허용됩니다 .abstract =
답변2
예를 들어 sed의 솔루션은 각 시작 및 끝 문자열을 다음으로 변환하는 것입니다.하나문자이므로 정규식을 사용하여 문자를 방지(부정)할 수 있습니다 [^…]
.
문자로 변환합니다( %
(시작) 및 #
(끝)이 파일에 나타날 수 없다고 가정하고 나중에 자세히 설명합니다):
<<<infile sed 's/abstract =/%/g; s/},\n/#/g'
그런 다음 첫 번째 항목에서 선택(및 삭제)할 수 있습니다.시작( %
)특징처음으로끝( #
) 문자 뒤:
sed 's/%[^#]*#//g'
[^#]
게임을 플레이하는 데 필요한욕심이 없다.
일부 구분 문자가 여전히 존재할 수 있으므로 이를 복원해야 합니다.
sed 's/%/abstract =/g; s/#/},\n/g' # assuming GNU sed.
물론 패턴이 다른 줄에 나타날 수도 있으므로 위의 내용을 전체 파일에 모두 적용해야 합니다. 따라서 예약된 공간에 전체 파일을 캡처합니다.
sed 'H;1h;$!d;g;'
전체 명령줄에서 다음을 수행합니다.
<infile sed 'H;1h;$!d;g; s/abstract =/%/g; s/},\n/#/g;
s/%[^#]*#//g ;
s/%/abstract =/g; s/#/},\n/g'
선택한 문자가 입력 파일에 존재할 가능성이 있는 경우 텍스트 파일에 존재하지 않는 다른 명시적 구분 기호를 선택할 수 있습니다.
ASCII에서 SOH(헤더 시작) 및 STX(텍스트 시작)로 01
알려진 값이 있는 문자(바이트) 02
는 "제어 문자"이며 텍스트 파일에서는 매우 드뭅니다. 이를 사용하려면 쉘 스크립트를 작성하는 것이 좋습니다.
#!/bin/bash
start=$'\1'
end=$'\2'
startpattern='abstract ='
endpattern=$'},\\\n' # The newline needs a `\` for sed to work.
sed 'H;1h;$!d;g;
s/'"$startpattern"'/'"$start"'/g;
s/'"$endpattern"'/'"$end"'/g;
s/'"$start"'[^'"$end"']*'"$end"'//g;
s/'"$start"'/'"$startpattern"'/g;
s/'"$end"'/'"$endpattern"'/g' <infile
답변3
당신 말이 맞습니다. 여기에서는 이와 같은 질문이 셀 수 없이 많이 제기되었습니다. 얼마나 멀리 갈 것인가?
sed '/abstract.*{/ {:L; /}/{d; b;}; N; bL; }' file
이해합니다? 일치 후에 abstract
는 필요한 경우 찾을 때까지 반복됩니다 }
.
편집하다:수정된 요청 허용:
sed '/abstract.*{/ {:L; /},$/{d; b;}; N; bL; }' file
답변4
Perl 코드가 거의 완성되었습니다. 몇 가지만 수정하면 됩니다.
perl -0777pe 's/abstract = .*?\},\n/\n/msg'
/s 플래그는 .를 개행과 일치시키고 .*?를 비탐욕적으로 만듭니다.