LINUX.ORG.RU

read: как считать строку в массив?

 


0

1

Вы конечно думали, что вопрос простой, а на самом деле он не такой уж и простой, как думали вы, ага :)
Смотрите, я всегда делал вот так, и это совершенно беззаботно работало на всех версиях BASH:

s='a.b.c.d'
svIFS="$IFS"
IFS='.'
arr=($s)
IFS="$svIFS"
После этого у нас в массиве arr: [0]='a' [1]='b' и т.д. Теперь хочу сделать тоже самое командой read:
declare -a arr
svIFS="$IFS"; IFS='.'
read -a arr
IFS="$svIFS"
В вся строка $s, это не то, чего я хотел
Ну ок, давайте так что ли:
declare -a arr
s='a.b.c.d'
read -d'.' -a arr
Теперь arr[0]='a', остальные элементы пусты.

Вопрос в оригинальном звучании: какого хрена?!!
Вопрос, скорректированный цензурой: возможно, я что-то делаю неверно, как сделать так, чтобы всё было ОК?

★★★★★

УМВР, ЧЯДНТ?

c0@c4 ~$ IFS='.'
c0@c4 ~$ declare -a arr
c0@c4 ~$ read -a arr
1.2.3.4.5
c0@c4 ~$ echo ${arr[1]}
2
c0@c4 ~$ echo ${arr[2]}
3
read -d не прокатит, ибо: -d delim — сontinue until the first character of DELIM is read, rather than newline

т.е. оно выйдет после первой точки, и само собой остальные элементы массива останутся пустыми.

cx ★★
()

1)

abw@abw 7 ~ $ IFS='.' read -a a <<< «b.c.d.» ; echo a0=${a[0]} a1=«${a[1]}» a2=«${a[2]}»
a0=b a1=c a2=d

(declare здесь не нужно, read делает unset)
так что, видимо, ты где-то зевнул.

2) -d определяет завершитель строки, а не разделитель полей, так что и не должно работать.

ABW ★★★★★
()
Ответ на: комментарий от cx

Понял! Проблема была в том, что я наспех делал вот так:

s='a.b.c.d'
read -a arr <<<$s
А нужно было вот так:
s='a.b.c.d'
read -a arr <<<"$s"
Двойные экранирующие скобки как всегда рулят. В данном случае IFS повлиял на конструкцию «<<<», так что в действительности read и считал только символ «a», всё остальное, очевидно, является уже «следующей записью».

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Главное во всём этом, что конструкция

arr=($s)
Куда проще и естественнее любого read'а. Вот если бы -d позволял избавиться от сохранения/восстановления IFS - это сэкономило бы целых 3 оператора в коде, и тогда я бы безусловно использовал read.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

bash(1):

A simple command is a sequence of optional variable assignments followed ...

IFS='.' read ...
сохранять/восстанавливать не надо.
В функциях можно использовать 'local IFS=...'

ABW ★★★★★
()
Ответ на: комментарий от ABW

Блин, а кстати да ведь, всё верно! Ну и что, что IFS-внутренняя переменная BASH'а, всё равно же ж переменная :)

DRVTiny ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.