현재 닫는 괄호가 앞에 오지 않은 모든 개행 문자를 제거하려고 하므로 다음 표현식을 생각해 냈습니다.
sed -r -i -e ":a;N;$!ba;s/([^\)])\n/\1/g;d" reallyBigFile.log
더 작은 파일에서는 작업을 수행하지만 내가 사용하는 이 큰 파일( 3GB
)에서는 잠시 동안 작동한 다음 메모리 부족 오류가 발생합니다.
sed: Couldn't re-allocate memory
이 문제에 직면하지 않고 이 작업을 수행할 수 있는 방법이 있습니까? 사용 sed
자체는 필수는 아니며, 그냥 사용하고 싶었습니다.
답변1
처음 세 명령이 범인입니다.
:a
N
$!ba
이렇게 하면 전체 파일을 한 번에 메모리로 읽어 들입니다. 다음 스크립트는 한 번에 하나의 세그먼트만 메모리에 유지할 수 있습니다.
% cat test.sed
#!/usr/bin/sed -nf
# Append this line to the hold space.
# To avoid an extra newline at the start, replace instead of append.
1h
1!H
# If we find a paren at the end...
/)$/{
# Bring the hold space into the pattern space
g
# Remove the newlines
s/\n//g
# Print what we have
p
# Delete the hold space
s/.*//
h
}
% cat test.in
a
b
c()
d()
e
fghi
j()
% ./test.sed test.in
abc()
d()
efghij()
이 awk 솔루션은 각 줄을 인쇄하므로 한 번에 메모리에 한 줄만 남습니다.
% awk '/)$/{print;nl=1;next}{printf "%s",$0;nl=0}END{if(!nl)print ""}' test.in
abc()
d()
efghij()
답변2
완벽함을 위해 Perl 솔루션은 다음과 같습니다.perl -p -e '/)$/ || chomp'
대칭을 위해: 스크립트를 루프로 감싸고 한 줄씩 읽고 인쇄합니다. /script -p
표현식은 줄 끝에서 일치하며, 일치하지 않으면(일치가 false) 계속해서 줄 바꿈을 제거합니다. 끝.-e
)
chomp
답변3
이것을 사용하십시오 :
sed -i -z -u 's/\n/ /g' reallyBigFile.log
-z, --null-data
NUL 문자로 줄을 구분합니다.
-u, --unbuffered는
입력 파일에서 최소한의 데이터를 로드하고 출력 버퍼를 더 자주 플러시합니다.