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
バイト分離記号)。
区切り文字を読み取るとは、読み取らないようにするために一度に1バイトずつ読み取る必要があることを意味します(特にパイプなどのナビゲートできない入力の場合)。過去区切り記号のため非効率的です。
代わりにロギングを使用することをお勧めします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>