다음과 같은 바이너리 sed유사 유틸리티입니다.bbe

다음과 같은 바이너리 sed유사 유틸리티입니다.bbe

레코드 끝에 줄 바꿈을 추가하지 않는 프로그램에 의해 생성된 일부 파일이 있습니다. 레코드 사이에 줄바꿈을 추가하고 싶습니다. 간단한 sed 스크립트를 사용하여 이 작업을 수행할 수 있습니다.

sed -e 's/}{/}\n{/g'

문제는 입력 파일의 크기가 여러 GB이므로 sed에 대한 입력 줄의 길이가 여러 GB라는 것입니다. sed는 메모리에 한 줄을 저장하려고 시도하지만 이 경우에는 작동하지 않습니다. 해당 옵션을 시도했지만 --unbuffered속도가 느려지고 올바르게 완료되지 않는 것 같습니다.

답변1

다른 도구를 사용하여 입력 레코드 구분 기호를 설정할 수 있습니다. 예를 들어

  • perl -pe 'BEGIN{ $/="}{" } s/}{/}\n{/g' file
    

    특수 변수 $/는 입력 레코드 구분 기호입니다. }{로 끝나는 줄을 정의하도록 설정합니다 }{. 이렇게 하면 전체 내용을 메모리로 읽지 않고도 원하는 것을 얻을 수 있습니다.

  • 모하거나 꾸물거리다

    awk -v RS="}{" -vORS= 'NR > 1 {print "}\n{"}; {print}' file 
    

    같은 생각이에요. RS="}{"레코드 구분 기호를 로 설정한 }{다음 , }개행 {(첫 번째 레코드 제외) 및 현재 레코드를 인쇄합니다.

답변2

Perl이 구조에 옵니다:

perl -i~ -e ' $/ = \1024;
              while (<>) {
                  print "\n" if $closing and /^{/;
                  undef $closing;
                  s/}{/}\n{/g;
                  print;
                  $closing = 1 if /}$/;
              } ' input1 input2

1024바이트 단위로 파일을 읽도록 $/설정 합니다 . \1024이 변수는 한 블록이 로 끝나고 다음 블록이 로 시작하는 $closing경우를 처리합니다 .}{

답변3

당신이 해야 할 일:

{ <infile tr \} \\n;echo {; } | paste -d'}\n' - /dev/null >outfile

이것이 아마도 가장 효율적인 솔루션일 것입니다.

이는 {}가능한 모든 추적 데이터를 보호합니다. 다른 tr프로세스를 사용하면 이를 교체하고 첫 번째 필드의 머리 부분에 빈 줄을 추가할 수 있습니다 {. 좋다...

tr {} '}\n'| paste -d{\\0 /dev/null - | tr {}\\n \\n{}

따라서 첫 번째는 don의 예제 데이터를 사용하여 다음과 같습니다.

printf '{one}{two}{three}{four}' |
{ tr \} \\n; echo {; }           |
paste -d'}\n' - /dev/null
{one}
{two}
{three}
{four}
{}

...두번째도 역시...

printf '{one}{two}{three}{four}'      |
tr {} '}\n'| paste -d{\\0 /dev/null - |
tr {}\\n \\n{}
#leading blank
{one}
{two}
{three}
{four}

두 번째 예에는 후행 줄 바꿈이 없습니다. 첫 번째 예에는 하나가 있지만.

답변4

다음과 같은 바이너리 sed유사 유틸리티입니다.bbe

이 경우에는 sed와 유사한 구문을 사용하는 것이 가장 쉽다고 생각합니다.

많은bbe유틸리티를 사용하는 것이 좋습니다({uni,linu}x 패키지 설치 eq를 통해 사용 가능 apt-get). 또는여기당신이 git 군중의 일부라면 나는 개인적으로 특정 링크를 검토하지 않았습니다.

1. 지원 s/before/after/숙어

sed와 유사한 작업을 지원하는 "바이너리 블록 편집기"입니다. 여기에는 s/before/after/필요한 매우 일반적인 대체 관용구가 포함됩니다. bbe관점 자체에서는 줄이 없기 때문에 명령 끝에 "전역 g"가 없다는 점에 유의하세요 .

빠른 테스트(참고 필요 -e):

$ echo hello | bbe -e 's/l/(replaced)/'

생산하다:

he(replaced)(replaced)o

2. 귀하의 특정 전환 }{상황 에서}\n{

따라서 캐리지 리턴이 없는 형식의 백만 개의 숫자가 있는 거대한 파일이 있는 경우 {1}{2}{3}쉽게 교체 하고 한 줄에 하나의 숫자를 가질 수 있습니다.{1000000}}{}\n{

다음 명령을 사용합니다 bbe.

bbe -e 's/}{/}\n{/'

이 zsh 루프에서 테스트한 대로 꼬리만 잡습니다.

$ for ((num=0; num<1000000; num++)) do; echo -n "{$num}"; done | bbe -e 's/}{/}\n{/' | tail

그러면 다음과 같은 결과가 생성됩니다.

{999990}
{999991}
{999992}
{999993}
{999994}
{999995}
{999996}
{999997}
{999998}
{999999}

(물론 후행 캐리지 리턴이 없습니다.)

관련 정보