Ошибка: «Системе не удается найти указанный файл» при использовании флага -r - PullRequest
0 голосов
/ 07 марта 2019

Использование cygwin bash в Windows XP.Версия Bash: 4.3.46 (7) -релиз.Минимальный рабочий пример, сортировка массива в обратном порядке:

#!/bin/bash
array=("a c" b f "3 5")
IFS=$'\r\n' sorted=($(sort -r <<<"${array[*]}"))
printf "[%s]\n" "${sorted[@]}"

Ошибка в cygwin:

-rThe system cannot find the file specified.

В Linux работает нормально.Ошибка вызвана флагом -r.Как исправить?

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Похоже, ваша версия sort не поддерживает флаг -r.Вы можете ...

  • найти в man sort эквивалентную опцию.
  • Сортировать в обычном порядке и перевернуть отсортированный вывод, используя другую команду, например tac (в обратном порядкеcat), или если это недоступно perl -e 'print reverse <>'.
    Пример: Вместо sort -r <<< "string" используйте sort <<< "string" | tac.

Пожалуйста, имейте такжепосмотрите Ответ Гленна Джекмана о возможных проблемах в вашем сценарии.

1 голос
/ 07 марта 2019

Я не думаю, что подобная работа с 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 делает это:

  1. она анализирует команду и видит IFS=something и sorted=something, отмечает их как присваивания переменных, выводит их из командной строки
  2. затем не находит ничего другого для выполнения в качестве команды,
  3. , затем, слева направо, присваивает эти переменные в текущей оболочке
    1. IFS имеет значение $'\r\n
    2. во время обработки отсортированного назначения bash выполняет свои расширения:
    3. выполняется подстановка команды:
      1. "${array[*]}" раскрывается в строку a c\rb\rf\r3 5, поскольку расширение параметра [*] присоединяется кэлементы массива, использующие первый символ из $ IFS.
      2. sort -r <<<$'a c\rb\rf\r3 5', так как ему дается одна строка ввода, возвращает ввод без изменений.
    4. теперь у нас есть sorted=($'a c\rb\rf\r3 5'), и поскольку подстановка команд не заключена в кавычки, слово spliпроисходит: строка разделяется с использованием символов IFS в качестве разделителей
    5. , поэтому мы получаем 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" !
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...