#shell
Вопрос:
Почему я продолжаю получать «Ожидаемый унарный оператор», даже если мой код выполняется и выводится правильно? Это просто простая сортировка пузырьков массива.
#!/bin/bash
declare -a array
hold=0
echo "Input length of array: "
read length
for((i = 0; i < length; i ))
do
echo "Enter number: "
read input
array =($input)
done
echo " "
echo "Elements in array: "
echo "${array[*]}"
echo " "
echo "Sorted Array"
for((i = 0; i < $length; i ))
do
for((j = 0; j < $length; j ))
do
if [ ${array[j]} -gt ${array[$((j 1))]} ]
then
hold=${array[j]}
array[$j]=${array[$((j 1))]}
array[$((j 1))]=$hold
fi
done
done
echo "Sorted Elements in array: "
echo "${array[*]}"
Комментарии:
1. Пожалуйста, отформатируйте свой код в вопросе, прочитайте минимальные требования, как задавать вопросы, так как перед тем, как помочь вам, я должен исправить ваш пример кода
2. Реализация пузырьковой сортировки — это пустая трата времени. Вы не пишете подобные программы в сценарии оболочки: вы пишете код, который запускает другие программы.
Ответ №1:
Используйте (( )) для математических операций, код будет более читаемым, поскольку вам не нужны специальные символы https://github.com/koalaman/shellcheck/wiki/SC2219
ваше проблемное место: if [ ${array[j]} -gt ${array[$((j 1))]} ]
заменить на if (( array[j] > array[j 1] ))
Улучшенная версия вашего кода :
#!/bin/bash
declare -a array
declare hold=0
# echo "Input length of array: "
#read length
#for (( i = 0; i < length; i )); do
# echo "Enter array number: $i" ;
# read input
# array =($input)
# done
array=(6 7 2 3 8 9)
length=${#array[@]}
echo "************************"
echo "Elements in array: "
echo "${array[*]}"
echo "************************"
for (( i = 0; i < length; i )); do
for (( j = 0; j < length -1 ; j )); do
#echo "iteration i/j - $i/$j ${array[*]} "
if (( array[j] > array[j 1] )); then
hold=array[j]
array[j]=array[j 1]
array[j 1]=hold
echo "change ${array[*]} "
fi
done
done
echo "************************"
echo "Sorted Elements in array: "
echo "${array[*]}"
echo "************************"
Комментарии:
1.Shellcheck предупреждает Вместо
let expr
, предпочитаю(( expr ))
.2. Вам не нужно
let
или((...))
для назначений. Индексы массива вычисляются в арифметическом контексте.array[j]=array[j 1]
работает нормально.3. Аргумент без кавычек to
let
подлежит разделению на слова и расширению глобуса, как и любая другая обычная команда. Надуманный, но действительный пример:array=(5 7 9); j=0; array1=42; touch "arrayj=array1"; set -x; let array[j]=array[j 1]; set x; declare -p array arrayj; ((array[j] = array[j 1])); declare -p array arrayj
4. проверено здесь: replit.com/languages/bash вот что у меня получилось: main.sh : строка 27: j 1: превышен уровень рекурсии выражения (маркер ошибки — «j 1»)
5. Вы упустили важное исправление: завершение внутреннего цикла до
j
того, как оно станет слишком большим.