Greg Wooledge wrote in <20250112215505.gb27...@wooledge.org>: |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