Я не думаю, что подобная работа с IFS даст вам результаты, к которым вы стремитесь.Попробуйте это:
#!/bin/bash
array=("a c" b f "3 5")
readarray -t sorted < <(printf "%s\n" "${array[@]}" | sort -r)
printf "[%s]\n" "${sorted[@]}"
Какие выходные данные
[f]
[b]
[a c]
[3 5]
Я думаю, что ваша трудность заключается здесь:
IFS=$'\r\n' sorted=($(sort -r <<<"${array[*]}"))
Ссылаясь на Простая командаРасширение , bash делает это:
- она анализирует команду и видит
IFS=something
и sorted=something
, отмечает их как присваивания переменных, выводит их из командной строки - затем не находит ничего другого для выполнения в качестве команды,
- , затем, слева направо, присваивает эти переменные в текущей оболочке
- IFS имеет значение
$'\r\n
- во время обработки отсортированного назначения bash выполняет свои расширения:
- выполняется подстановка команды:
"${array[*]}"
раскрывается в строку a c\rb\rf\r3 5
, поскольку расширение параметра [*]
присоединяется кэлементы массива, использующие первый символ из $ IFS. sort -r <<<$'a c\rb\rf\r3 5'
, так как ему дается одна строка ввода, возвращает ввод без изменений.
- теперь у нас есть
sorted=($'a c\rb\rf\r3 5')
, и поскольку подстановка команд не заключена в кавычки, слово spliпроисходит: строка разделяется с использованием символов IFS в качестве разделителей - , поэтому мы получаем
sorted=("a c" b f "3 5")
, порядок которого совпадает с исходным массивом.
Мой комментарий к окончанию строки вашего скрипта:
Когда файл сценария имеет окончания строки CRLF в стиле DOS, первая строка рассматривается bash как
array=("a c" b f "3 5")$'\r'
Это означает, что array
является не массивом, а единственным значением:
$ IFS=$' \t\n' # the default value
$ array=("a c" b f "3 5")$'\r'
$ declare -p array
"eclare -- array="(a c b f 3 5)
# ......^^ _not_ "-a" !