Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: more splitting





On 2026-04-16 04:11, Philippe Altherr wrote:

function hex()
{
  if (($#)); then
    echo "--- Front door --------------"
    print -rC1 -- ${(q+)@}
    echo "\n-----------------------------\n"
    for element ("$@") print -rn -- $element | od -vAx -tx1 -tc
  fi
  if [[ -p /dev/fd/0 ]]; then
    local var c; while read -u 0 -k 1 c; do var+=$c; done
    echo "--- Back door ---------------"
    print -rC1 -- ${(q+)var}
    echo "\n-----------------------------\n"
    for element ("$var") print -rn -- $element | od -vAx -tx1 -tc
  fi
}

The line "local var c; while read -u 0 -k 1 c; do var+=$c; done" is rather verbose and most likely very inefficient but it's the only way I know to fully read what's at the back door including any trailing newline characters.
Speed is never an issue, the only thing that matters is getting an absolutely clear understanding of how the array was built.

Thanks Philippe, that has a pleasing symetry.  The way you capture the pipe is elegant, it has a rightness about it.  I'd not have imagined that one could use the front door and the back door at the same time.  And, all else equal it's probably more othodox to pass the value of the variable than the name. If it's at the front door the splitting is retained.

It really is impossible to know from the pipe version where the input array was split, the information no longer exists.  Still, there is an ambiguity:

% var=("a b" c$'\n''d e f'' ''g h' ij); hhex $var
--- Front door --------------
'a b'
$'c\nd e f g h'
ij

-----------------------------

000000  61  20  62
         a       b
000003
000000  63  0a  64  20  65  20  66  20  67  20  68
         c  \n   d       e       f       g       h
00000b
000000  69  6a
         i   j
000002

% var2=( ${(f)var} ); hhex $var2
--- Front door --------------
'a b c'
'd e f g h ij'

-----------------------------

000000  61  20  62  20  63
         a       b       c
000005
000000  64  20  65  20  66  20  67  20  68  20  69  6a
         d       e       f       g       h       i   j
00000c

It seems that the splitting char is always removed, thus one can't look at $var2 and determine that it was created via split on newlines, one might just as well conclude that it was split on spaces, with a space between 'c' and 'd' instead of a newline.  This seems to me an imperfection, tho obviously one would have to go back to the 70s to have done anything about it.  In the interests of perfect information, I wonder if there's any way that even the 'od' output could inform us that the output of $var2 is an array split on newlines?  I suspect that 'od' has no way of knowing.








Messages sorted by: Reverse Date, Date, Thread, Author