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

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

stdin문자열 구분 기호가 발견될 때부터 읽기를 시작하고 싶습니다 MARKER=$'\0'"BRISH_MARKER". 나는 시도했다:

❯ unset br ; print -rn -- hi${MARKER}world |   {  IFS= read -d "$MARKER" -r br ; cat -v } ; echo ; typeset -p br

이것은 만든다:

BRISH_MARKERworld
typeset br=hi

따라서 read주어진 구분 기호의 첫 번째 문자만 사용됩니다 \0. 전체 문자열을 사용하고 싶습니다. 이 목표를 어떻게 달성할 수 있나요?

제가 해결하려는 문제는 지속적으로 데이터 스트림을 zsh 프로세스에 공급하는 프로세스가 있고 구분 기호를 사용하여 데이터를 다른 값으로 분할해야 한다는 것입니다. 처음에는 그냥 사용했는데 \0포함된 값을 사용할 수 없어서 \0현재 MARKER.

답변1

read -d단일 문자 구분 기호에만 작동합니다. ( 단일 문자 구분 기호에만 작동합니다. bash)ksh93바이트분리 기호).

구분 기호를 읽는다는 것은 읽지 않도록 하기 위해 한 번에 한 바이트씩 읽어야 함을 의미합니다(특히 파이프와 같이 탐색할 수 없는 입력의 경우).과거구분 기호로 인해 비효율적입니다.

대신 로깅을 사용하는 것이 좋습니다 length:value.

write-record() {
  set -o localoptions +o multibyte
  print -rn -- "$#1:$1"
}
read-record() {
  set -o localoptions +o multibyte
  local len

  # note that in current versions of zsh, read -k0 (for empty records)
  # returns a non-zero exit status.
  eval "$1="
  IFS= read -rd: len || return
  ((len == 0)) || read -u0 -k "$len" "$1"
}

( multibyte해당 길이(바이트)를 로컬에서 비활성화하고 여기에서 쓸모 없는 문자 인코딩/디코딩을 피하십시오.)

예를 들면 다음과 같습니다.

$ (write-record $'é\0x'; write-record $'foo\0MARKER') | { read-record a && read-record b; printf "<%q>\n" "$a" "$b"; }
<é$'\0'x>
<foo$'\0'MARKER>

관련 정보