Попытка разбить строку на две переменные
Я пытаюсь разбить строку на две переменные (без использования цикла while):
var="hello:world"
IFS=':' read var1 var2 <<< $var
echo "var1: $var1"
echo "var2: $var2"
но я не получаю желаемого результата:
var1: 'hello world'
var2: ''
Может кто-нибудь объяснить, возможно ли это сделать (или аналогичным образом)?
Ответы
Ответ 1
Это ошибка в Bash 4.2. См. ответ chepner для правильного объяснения.
Это о котировках. Использование:
IFS=':' read var1 var2 <<< "$var"
^ ^
вместо
IFS=':' read var1 var2 <<< $var
См. результат:
$ IFS=':' read var1 var2 <<< "$var"
$ echo "var1=$var1, var2=$var2"
var1=hello, var2=world
Но
$ IFS=':' read var1 var2 <<< $var
$ echo "var1=$var1, var2=$var2"
var1=hello world, var2=
Ответ 2
FYI для будущих читателей:
После обсуждения этого вопроса с разработчиками, похоже, это действительно ошибка в bash
4.2 и исправлена в предстоящей версии 4.3. Из журнала изменений ветвей разработки
рррр. Исправлено несколько проблем с IFS, когда оно появилось во временной среде и используется в перенаправлении.
Несмотря на то, что всегда полезно указывать расширения параметров, код OP должен работать так, как предполагалось, без кавычек.
Вот объяснение ошибки. С кодом
var="hello:world"
IFS=':' read var1 var2 <<< $var
неуказанное $var
должно быть одним словом, так как оно не содержит символа в глобальном значении IFS
(то есть без пробела). read
должен видеть строку hello:world
. Поскольку он получил два аргумента, он должен применять разбиение по словам, используя его локальное значение IFS
, создавая hello
и world
, которые назначаются соответственно var1
и var2
.
Ошибка заключается в том, что строка здесь, как представляется, подвергается частичному расщеплению с использованием "пропущенного" значения IFS
, передаваемого в read
. В результате строка становится hello world
, но все еще рассматривается как read
как одно слово. Поскольку это слово не содержит :
, read
не разбивает его на два слова, а вся строка присваивается var1
.
В bash
4.3, как задокументировано, расширение $var
не претерпевает расщепления слов в качестве аргумента оператору <<<
; код
var="hello:1:2 world"
IFS=: read var1 var2 <<< $var
устанавливает var1
в hello
и var2
в 1:2 world
.