bash: 표준 입력에서 문자열 구분 기호까지 읽습니다.

bash: 표준 입력에서 문자열 구분 기호까지 읽습니다.

임의의 바이트를 포함하는 두 개의 파일이 있다고 가정해 ./delimiter보겠습니다 ./data.

./data바이트 시퀀스가 ​​처음 나타날 때 까지 읽고 제외하고 싶습니다 ./delimiter.

Bash를 사용하여 이 작업을 어떻게 수행할 수 있나요?

예:

  • 콘텐츠./delimiter
    world
    
  • 콘텐츠./data
    helloworld
    
  • 예상되는 결과:
    hello
    

유사/동등한 질문:

참고: read -d delim문자열이 아닌 단일 문자 구분 기호만 지원하기 때문에 문제가 해결되지 않습니다. 또한 바이트를 지원하지 않는 변수에 결과를 저장합니다 NUL. 나는 출력을 원한다 stdout.

답변1

Perl이 구출하러 옵니다!

perl -e 'local $/;
         open $de, "<", "delimiter" or die $!;
         $/ = <$de>;
         open $da, "<", "data" or die $!;
         chomp( $first = <$da> );
         print $first;'

특수 변수$/다음을 통해 입력 레코드 구분 기호를 설정합니다.현지의이를 사용하여 전체 파일을 읽습니다("slurping"이라고도 함). 그런 다음 다이아몬드 연산자를 사용하여 파일의 내용을 읽고 delimiter해당 내용에 구분 기호를 설정합니다. 그런 다음 파일에서 첫 번째 레코드를 읽습니다 data.씹다레코드 구분 기호를 추출합니다.

답변2

zsh(변수에 임의의 바이트 시퀀스를 저장할 수 있는 유일한 셸)을 사용하고 data일반 delimiter(또는 적어도 mmap() 가능) 파일이라고 가정하면 다음을 수행할 수 있습니다.

zmodload zsh/mapfile

set +o multibyte # necessary so sequences of bytes that
                 # happen to form valid characters may be
                 # broken in the middle if necessary.

firstpart=${mapfile[data]%%$mapfile[delimiter]*}

또는:

zmodload zsh/mapfile
set +o multibyte # necessary so sequences of bytes that
                 # happen to form valid characters may be
                 # broken in the middle if necessary.

delimiter=$mapfile[delimiter]
parts=( ${(ps[$delimiter])mapfile[data]} )

firstpart=$parts[1]

(매우 효율적이거나 수백 메가바이트보다 큰 파일로 잘 확장될 것이라고 기대하지 마십시오).

이 섹션을 그대로 인쇄하려면 다음을 사용하세요.

print -rn -- $firstpart

또는

printf %s $firstpart

관련 정보