Каким образом разделение строки на массив путем "чтения" с помощью разделителя слов IFS в bash создает дополнительный пробел?
Имея только один символ для IFS, он отлично работает:
shell@kernel: ~> l="2.4.3"; IFS="." read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2
4
3
Хотя для IFS есть два символа, генерируется дополнительный пробел
shell@kernel: ~> l="2->4->3"; IFS="->" read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2
4
3
shell@kernel: ~> l="2..4..3"; IFS=".." read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2
4
3
Как я могу избавиться от лишнего элемента в массиве?
3 ответа
Решение
Продолжая комментарий, вы можете либо проверить наличие пустого элемента перед сохранением значения в массиве, либо иметь дело с пустым значением, когда echo
Это. Честно говоря, проще сделать последнее, например,
l="2->4->3"; IFS="->" read -a la <<< "$l"; \
for ((i = 0; i < ${#la[@]}; ++i)) do \
[ -n "${la[i]}" ] && echo ${la[$i]}; done
Выход
2
4
3
Вы можете преобразовать разделитель ->
в один символ с:
l="2->4->3"
IFS="-" read -a la <<< "${l//->/-}"
printf '%s' "${la[@]}"
Если есть риск, что строка может содержать дополнительные -
затем используйте маловероятный символ, который будет в строке:
IFS="┵" read -a la <<< "${l//->/┵}"
Я бы просто использовал sed для замены разделителя
видите, повторное использование вашего скрипта + sed
bash$ l="2->4->3"
bash$ read -a la <<< "$(echo $l | sed 's/->/ /g')"
bash$ for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done
2
4
3
но я думаю, что сделал бы это совсем по-другому
bash$ l="2->4->3"
bash$ for x in `echo $l | sed 's/->/ /g'`; do echo $x; done
2
4
3
надеюсь это поможет