Greg Wooledge wrote in
<[email protected]>:
|On Sun, Jan 12, 2025 at 16:26:04 -0500, Chet Ramey wrote:
|>> In this case, we get the "expected" result:
|>
|> You just restated the original example while ignoring the part of my
|> message about looking for additional input after you find a delimiter.
|
|Right. You explained why it works the way it does. But from a user's
|point of view, it's just unexpected behavior.
|
|I'm not asking for anything to be changed, because I know that's not an
|option. All I can do at this point is try to make sure people are
|aware that the read command has this behavior, and that they should
|plan around it.
|
|If one is reading a CSV file, then there are approprate tools that can
|be used. This part has been covered.
|
|However, a common reason someone uses "IFS=: read -r var1 rest"
|is because they're reading a text file/stream in which each line has
|a delimited field, followed by a delimiter, followed by a bunch of
|unpredictable free text. Maybe it's a filename, or a description, or
|something a user typed.
|
|If one wants everything after the delimiter to be stored in the "rest"
|variable *without modification*, the read command shown above won't
|do the job. It modifies the line in a very specific edge case, which
|one's testing probably won't encounter.
|
|That's the pitfall.
|
|As a workaround, one may append an extra delimiter to the line, then
|do the read, then strip the added delimiter. That's on the wiki page.
|
|Or, one may read the entire line without field splitting it at all,
|and then use ${line%%:*} and ${line#*:} to split it.
Btw my MUA (will) support(s) (with the next release) storing in "a
result set" (that i "invented" because i needed a mechanism
exactly like $*/$@/$#/$1.. etc, but alongside, for example for
storing result matches of regular expressions of if etc).
printf 'ab,cd,ef,\nab,ef,\nab,cd,ef,,,x,y,z\n' |
s-nail -R:/ -Snoheader \
-Y 'set ifs=,; read field1 rest; unset ifs; var field1 rest' \
-Y 'set ifs=,; read field1 rest; unset ifs; var field1 rest' \
-Y 'set ifs=,; read ^; unset ifs; var ^# ^0 ^1 ^2 ^*' \
-Yxit
s-nail version v14.9.25-636-gc7c14cee09-dirty. Type `?' for help
set field1=ab
set rest=cd,ef,
set field1=ab
set rest=ef
#^#=8
#^0=16
#^1=ab
#^2=cd
#^*='ab cd ef x y z'
Should be doable for bash in the "no-argument" case, which
currently works though POSIX requires at least one argument:
$ </dev/null dash -c 'read'
dash: 1: read: arg count
$ </dev/null bash -c 'read'
$ prt-get info bash
Name: bash
Path: /usr/ports/core
Version: 5.2.37
Release: 1
Description: An sh-compatible command language interpreter
URL: https://tiswww.case.edu/php/chet/bash/bashtop.html
Maintainer: CRUX System Team, core-ports at crux dot nu
Dependencies: readline
Busybox sh has the same bug.
Ie, like $BASH_REMATCH, $BASH_READFIELDS or so.
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
|
|In Fall and Winter, feel "The Dropbear Bard"s pint(er).
|
|The banded bear
|without a care,
|Banged on himself for e'er and e'er
|
|Farewell, dear collar bear