Specifying IFS delimiter in while loop

i have data that is delimited with #x#:

file1#x#file2#x#file3
file4#x#file5#x#file6

data is stored in a variable called ALLMYDATA:

echo "${ALLMYDATA}" | while IFS="#x#" read -r line junk
do
echo ${line}
done

it appears IFS does not allow the specification of more than one character as a delimiter. is there a way around this? im looking for a solution that does not make any external calls to system tools. i dont want to awk or perl this.

I'd like to use available shell functions.

IFS can be more than one character ie. a string, but not a group of characters.

You want to do something like this?

$ OLDIFS=$IFS
$ IFS="#x#"
$ ALLMYDATA="file1#x#file2#x#file3
file4#x#file5#x#file6"
$ echo $ALLMYDATA | while read LINE; do IFS=$OLDIFS; echo $LINE| while read A B C; do echo "$A -- $B -- $C";done ; done
file1 -- file2 -- file3
file4 -- file5 -- file6
2 Likes

If you are using bash, would you be better with this as your loop?:-

ALL_MY_DATA=$(sed 's/#x#/ /g' <<< $ALLMYDATA)                    # Replace the three characters with a space all through the record
for LINE in $ALL_MY_DATA
do
   echo $LINE
done

However it seems that you might only want the first field of each row. Is that right?

If so, then you could perhaps work on a variation of:-

while read LINE
do
   echo "${LINE%%#x#*}"                                          # Trim off everything after the first #x#
done <<< "$ALLMYDATA"

If you are using ksh we can work it out for that too.

I hope that this helps,
Robin

1 Like

How about ( bash !)

echo "${ALLMYDATA//#x#/ }" | while read -r line junk; do echo $junk, $line; done

?

2 Likes

this is ideal however, its not portable. some OSes dont have bash..i.e. sunos and aix.

---------- Post updated at 09:30 AM ---------- Previous update was at 09:28 AM ----------

im not only looking for the first field. its just in the example i provided, the first field happened to be the field i was looking for. im going to be interested in all fields.

---------- Post updated at 09:48 AM ---------- Previous update was at 09:30 AM ----------

ALL_MY_DATA=$(sed 's/#x#/ /g' <<< $ALLMYDATA)                    # Replace the three characters with a space all through the record
for LINE in $ALL_MY_DATA
do
   echo $LINE
done

this seems to work but it appears if the data contains an "x" it gets read of it and replaces it with a space.

No. That sed command will not change x to a space unless it is surrounded by octothorps (unless you also still have x as a character in IFS ). If $IFS expands to a string containing x , then the field splitting performed when expanding $ALL_MY_DATA in the line:

for LINE in $ALL_MY_DATA

will discard any x characters remaining in ALL_MY_DATA after the sed completes.

After running your earlier code, did you remember to reset IFS to the default <space>, <tab>, and <newline> before running the above code?

1 Like