Shell
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 程序,並且需要使用分隔符將數據分解為不同的值。我最初使用 just
\0
,但這不允許我使用包含 的值\0
,所以我嘗試使用目前的MARKER
.
Yes
read -d
僅適用於單字元分隔符(在bash
and中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>