回答“为什么”问题
IFS是字段分隔符,而不是记录分隔符(默认记录分隔符是换行符,可以使用-d
参数更改为read
)。每次调用read
都会读取一个记录,并在字段边界可选地将其拆分成多个变量。
当你运行read -r part
时,你只读取一个记录(进入part
的记录),因此没有分隔要做:因此$part
包含整个记录,包括逗号。
处理IFS的替代方案
相比之下,如果您使用-a
指定目标作为数组(read -r -a parts
)或传递多个目标变量(read -r part1 part2 part3
),则会进行字段拆分。
与以下进行比较:
while IFS=, read -r key value; do
echo "key=$key, value=$value"
done <<EOF
hello,world
hi,neighbor
EOF
同样地,可以将一行读入一个数组:
while IFS=, read -r -a parts; do
printf 'Read %d parts: ' "${#parts[@]}"
printf '<%s> ' "${parts[@]}"
printf '\n'
done <<EOF
three,word,array
this,is,four,words
EOF
...预期产生:
Read 3 parts: <three> <word> <array>
Read 4 parts: <this> <is> <four> <words>
hello\nworld
。 您的输入字符串是包含两个字符\
和n
的一行,而不是两行。 - chepnerecho
将\n
替换为换行符本身(这很奇怪,因为在bash中这绝不是默认设置)。 - Charles Duffy#!/bin/bash
开头还是通过bash yourscript
运行的?如果你的解释器不是bash(例如,如果它是sh
),那么这就可以解释echo
的行为之谜了。 - Charles Duffy