\{{[}
텍스트 파일에 텍스트가 있고 문자열 자체를 포함하여 및 등의 문자열 사이에 있는 모든 내용을 제거하고 싶습니다 . {]}\}
이 두 문자열할 수 있는다른 줄에 있고 같은 줄에 있습니다. 두 경우 모두, 존재하다시작 부분이 있는 줄 \{{[}
, 그 앞의 텍스트가 삭제되는 것을 원하지 않습니다. 즉, 왼쪽의 텍스트 - 뒤의 텍스트도 마찬가지입니다 {]}\}
.
예는 다음과 같습니다. 콘텐츠가 포함된 텍스트 파일이 제공됩니다.
Bla Bla bla bla \{{[} more bla bla
even more bla bla bla bla.
A lot of stuff might be here.
Bla bla {]}\} finally done.
Nonetheless, the \{{[} show {]}\} goes on.
스크립트는 콘텐츠가 포함된 다른 텍스트 파일을 반환해야 합니다.
Bla Bla bla bla finally done.
Nonetheless, the goes on.
불행하게도 단순해 보이는 이 작업은 나에게 너무 어려웠다 sed
. 나는 매우 행복하다어느표준 Linux 시스템에 아무것도 설치할 필요가 없는 한 모든 언어 솔루션(C 및 일부 Java가 이미 설치되어 있음).
답변1
그리고 perl
:
perl -0777 -pe 's/\Q\{{[}\E.*?\Q{]}\}\E//gs'
전체 입력은 처리 전에 메모리에 로드됩니다.
\Qsomething\E
something
정규 표현식이 아닌 리터럴 문자열로 처리됩니다 .
일반 파일을 수정하려면 다음 -i
옵션을 추가하세요.
perl -0777 -i -pe 's/\Q\{{[}\E.*?\Q{]}\}\E//gs' file.txt
GNU를 사용 awk
하거나 다음 을 수행하십시오 mawk
.
awk -v 'RS=\\\\\\{\\{\\[}|\\{\\]}\\\\}' -v ORS= NR%2
거기서 우리는 정의합니다기록 구분 기호시작 또는 끝 태그 중 하나로 사용됩니다( 정규 표현식은 여기에서만 지원됩니다 gawk
) mawk
. RS
하지만 다시 정규식 연산자의 문자(백슬래시 {
, , ) [
와 백슬래시를 이스케이프해야 합니다. 왜냐하면 백슬래시는 인수( , ... -v
와 같은 것에 사용됨 )에 특수하므로 백슬래시가 많이 있기 때문입니다.\n
\b
그런 다음 우리가 해야 할 일은 다른 모든 레코드를 인쇄하는 것뿐입니다. 모든 홀수 레코드에 대해 NR%2
(true)입니다 .1
두 솔루션 모두 태그가 일치하고 부품이 중첩되지 않은 것으로 가정합니다.
최신 버전의 GNU를 사용하여 파일을 수정하려면 1 옵션을 awk
추가하세요 .-i /usr/share/awk/inplace.awk
^사용하지 마세요-i inplace
현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk
로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
답변2
sed -e:t -e'y/\n/ /;/\\{{\[}/!b' \
-e:N -e'/\\{{\[.*{\]}\\}/!N' \
-e's/\(\\{{\[}\).*\n/\1/;tN' \
-e'y/ /\n/;s/\\{{\[}/& /;ts' \
-e:s -e's/\(\[} [^ ]*\)\({\]}\\}\)/\1 \2/' \
-ets -e's/..... [^ ]* .....//;s/ //g;bt' \
<<""
#Bla Bla {]}\} bla bla \{{[} more bla bla
#even more bla bla bla bla. \{{[}
#
#A lot of stuff might be here.
#hashes are for stupid syntax color only
#Bla bla {]}\} finally {]}\} done.
#
#Nonetheless, the \{{[} show {]}\} goes \{{[} show {]}\} on.
#Bla Bla {]}\} bla bla finally {]}\} done.
#
#Nonetheless, the goes on.
그러나 더 좋은 방법이 있습니다. 대체 항목이 훨씬 적으며 .*
항상 사용하는 것이 아니라 한 번에 몇 문자씩 사용합니다 . 실제로 .*
이것이 사용되는 유일한 경우는 처음 발생하는 시작이 첫 번째 후속 끝과 확실히 쌍을 이루어 중간의 패턴 공간을 지울 때입니다. 나머지 시간에는 다음 구분 기호에 도달하기 위해 최대한 많이 삭제합니다 sed
. D
돈이 가르쳐줬어요.
sed -etD -e:t -e'/\\{{\[}/!b' \
-e's//\n /;h;D' -e:D \
-e'/^}/{H;x;s/\n.*\n.//;}' \
-ett -e's/{\]}\\}/\n}/' \
-e'/\n/!{$!N;s//& /;}' -eD \
<<""
#Bla Bla {]}\} bla bla \{{[} more bla bla
#even more bla bla bla bla. \{{[}
#
#A lot of stuff might be here.
#hashes are for stupid syntax color only
#Bla bla {]}\} finally {]}\} done.
#
#Nonetheless, the \{{[} show {]}\} goes \{{[} show {]}\} on.
#Bla Bla {]}\} bla bla finally {]}\} done.
#
#Nonetheless, the goes on.
그러나 RHS \n
개행 문자는 문자 그대로 백슬래시로 이스케이프된 개행 문자로 대체되어야 할 수도 있습니다.
보다 일반적인 버전은 다음과 같습니다.
#!/usr/bin/sed -f
####replace everything between START and END
#branch to :Kil if a successful substitution
#has already occurred. this can only happen
#if pattern space has been Deleted earlier
t Kil
#set a Ret :label so we can come back here
#when we've cleared a START -> END occurrence
#and check for another if need be
:Ret
#if no START, don't
/START/!b
#sigh. there is one. get to work. replace it
#with a newline followed by an S and save
#a copy then Delete up to our S marker.
s||\
S|
h;D
#set the :Kil label. we'll come back here from now
#on until we've definitely got END at the head of
#pattern space.
:Kil
#do we?
/^E/{
#if so, we'll append it to our earlier save
#and slice out everything between the two newlines
#we've managed to insert at just the right points
H;x
s|\nS.*\nE||
}
#if we did just clear START -> END we should
#branch back to :Ret and look for another START
t Ret
#pattern space didnt start w/ END, but is there even
#one at all? if so replace it w/ a newline followed
#by an E so we'll recognize it at the next :Kil
s|END|\
E|
#if that last was successful we'll have a newline
#but if not it means we need to get the next line
#if the last line we've got unmatched pairs and are
#currently in a delete cycle anyway, but maybe we
#should print up to our START marker in that case?
/\n/!{
#i guess so. now that i'm thinking about it
#we'll swap into hold space, and Print it
${ x;P;d
}
#get next input line and add S after the delimiting
#newline because we're still in START state. Delete
#will handle everything up to our marker before we
#branch back to :Kil at the top of the script
N
s||&S|
}
#now Delete will slice everything from head of pattern space
#to the first occurring newline and loop back to top of script.
#because we've definitely made successful substitutions if we
#have a newline at all we'll test true and branch to :Kil
#to go again until we've definitely got ^E
D
...코멘트가 없습니다...
#!/usr/bin/sed -f
t Kil
:Ret
/START/!b
s||\
S|
h;D
:Kil
/^E/{
H;x
s|\nS.*\nE||
}
t Ret
s|END|\
E|
/\n/!{
${ x;P;d
}
N
s||&S|
}
D
주석이 달린 버전을 클립보드에 복사하고 다음을 수행합니다.
{ xsel; echo; } >se.sed
chmod +x se.sed
./se.sed <se.sed
#!/usr/bin/sed -f
####replace everything between
#branch to :Kil if a successful substitution
#has already occurred. this can only happen
#if pattern space has been Deleted earlier
t Kil
#set a Ret :label so we can come back here
#when we've cleared a occurrence
#and check for another if need be
:Ret
#if no at the head of
#pattern space.
:Kil
#do we?
/^E/{
#if so, we'll append it to our earlier save
#and slice out everything between the two newlines
#we've managed to insert at just the right points
H;x
s|\nS.*\nE||
}
#if we did just clear we should
#branch back to :Ret and look for another , but is there even
#one at all? if so replace it w/ a newline followed
#by an E so we'll recognize it at the next :Kil
s|END|\
E|
#if that last was successful we'll have a newline
#but if not it means we need to get the next line
#if the last line we've got unmatched pairs and are
#currently in a delete cycle anyway, but maybe we
#should print up to our
답변3
파일이 test.txt이면 다음을 사용할 수 있습니다.
sed ':a;N;$!ba;s/\n/ /g' test.txt|sed 's/\\{{\[}.*{\]}\\}//'
첫 번째 sed는 모든 줄 바꿈을 제거하고 두 번째 sed는 태그 내의 텍스트를 제거합니다.
좀 더 일반적인 해결책이 필요한지 모르겠습니다.