누구나 메모리를 효율적으로 사용하여 문자열을 “이진”검색 / 바꾸기위한 비 라인 기반 도구를 알고 있습니까? 이 질문 도 참조하십시오 .
이 작업과 비슷한 + 2GB 텍스트 파일을 처리하려고합니다.
sed -e 's/>\n/>/g'
즉, 나는 이후에 발생하는 모든 줄 바꿈을 제거하고 싶지만 >
다른 곳에서는 제거하지 않기를 원합니다 tr -d
.
이 명령 ( 유사한 질문에 대한 답변 에서 얻은 )은 다음과 couldn't re-allocate memory
같이 실패합니다 .
sed --unbuffered ':a;N;$!ba;s/>\n/>/g'
C에 의지하지 않고 다른 방법이 있습니까? 나는 펄을 싫어하지만,이 경우 예외를 기꺼이
나는 데이터에서 발생하지 않는 문자를 확신하지 못하므로 \n
다른 문자로 임시 대체 하는 것이 가능하면 피하고 싶은 것입니다.
좋은 아이디어가 있습니까?
답변
이것은 정말로 Perl에서 사소한 것이므로 싫어해서는 안됩니다!
perl -i.bak -pe 's/>\n/>/' file
설명
-i
: 파일을 제자리에 편집하고라는 원본의 백업을 만듭니다file.bak
. 백업을 원하지 않으면perl -i -pe
대신 사용하십시오.-pe
: 입력 파일을 한 줄씩 읽고으로 주어진 스크립트를 적용한 후 각 줄을 인쇄하십시오-e
.s/>\n/>/
: 같은 치환sed
.
그리고 여기 awk
접근 방식이 있습니다 :
awk '{if(/>$/){printf "%s",$0}else{print}}' file2
답변
perl
솔루션 :
$ perl -pe 's/(?<=>)\n//'
설명
s///
문자열 대체에 사용됩니다.(?<=>)
lookbehind 패턴입니다.\n
개행과 일치합니다.
전체 패턴은 그 >
전에있는 모든 개행을 제거하는 것을 의미 합니다.
답변
이건 어때:
sed ':loop
/>$/ { N
s/\n//
b loop
}' file
GNU sed의 경우 질문에 따라 -u
( --unbuffered
) 옵션을 추가 할 수도 있습니다 . GNU sed는 간단한 단일 라이너로 이것을 기쁘게 생각합니다.
sed ':loop />$/ { N; s/\n//; b loop }' file
답변
sed
이 N
명령 과 함께 사용할 수는 있지만 다른 방법을 추가 할 때마다 패턴 공간에서 한 줄을 삭제하는 것이 요령입니다 (따라서 패턴 공간에는 전체를 읽지 않고 항상 두 개의 연속 된 줄만 포함됩니다) 파일)-시도
sed ':a;$!N;s/>\n/>/;P;D;ba'
편집 : Peteris Krumins의 유명한 Sed One-Liners를 다시 읽은 후 더 나은 sed
해결책이 있다고 생각 합니다.
sed -e :a -e '/>$/N; s/\n//; ta'
이것은 이미 >
끝에 일치 하는 경우에만 다음 줄을 추가하고 연속 일치하는 줄의 경우를 처리하기 위해 조건부로 루프 해야 합니다 (Krumin의 39입니다. 백 슬래시로 끝나는 경우 다음 줄을 추가하십시오 “\” 는 >
for \
를 결합 문자로 대체 하고 결합 문자가 출력에 유지된다는 사실을 제외하고는 정확히 제외됩니다 .
답변
sed
최종 개행없이 출력을 방출하는 방법을 제공하지 않습니다. N
기본적으로 사용하는 접근 방식 은 작동하지만 불완전한 줄을 메모리에 저장하므로 줄이 너무 길면 실패합니다 (sed implentations는 일반적으로 매우 긴 줄을 처리하도록 설계되지 않았습니다).
대신 awk를 사용할 수 있습니다.
awk '{if (/<$/) printf "%s", $0; else print}'
다른 방법은 tr
개행 문자를 “지루한”자주 발생하는 문자로 바꾸는 데 사용 하는 것입니다. 공간이 여기에서 작동 할 수 있습니다. 데이터의 모든 라인 또는 최소한 많은 라인에 나타나는 경향이있는 문자를 선택하십시오.
tr ' \n' '\n ' | sed 's/> />/g' | tr '\n ' ' \n'
답변
ed를 사용하는 것은 어떻습니까?
ed -s test.txt <<< $'/fruits/s/apple/banana/g\nw'