누구나 메모리를 효율적으로 사용하여 문자열을 “이진”검색 / 바꾸기위한 비 라인 기반 도구를 알고 있습니까? 이 질문 도 참조하십시오 .
이 작업과 비슷한 + 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'