Печать массива в скрипте bash - PullRequest
0 голосов
/ 04 марта 2020

Я пытаюсь написать скрипт, который принимает целые числа в качестве аргументов командной строки, возводит их в квадрат и затем показывает квадраты и сумму квадратов. Вот что у меня есть:

#!/bin/bash
if [ $# = 0 ]
    then 
        echo "Enter some numbers"
    exit 1
fi

sumsq=0 #sum of squares  
int=0 #Running sum initialized to 0  
count=0 #Running count of numbers passed as arguments  

while (( $# != 0 )); do 
    numbers[$int]=$1            #Assigns arguments to integers array
    square=$(($1*$1))           #Operation to square argument first arg by itself
    squares[$int]=$square       #Square of each argument
    sumsq=$((sumsq + square))   #Add square to total
    count=$((count+1))          #Increment count
    shift                       #Remove the used argument
done

echo "The squares are ${squares[@]}"
echo "The sum of the squares is $sumsq"
exit 0

У меня все работает как надо, кроме конца, где мне нужно отобразить квадраты. По какой-то причине он печатает только последний квадрат. Я попытался изменить e${squares[@]}" на ${squares[*]}", а также дважды заключить его в кавычки, но он по-прежнему печатает только последний квадрат. В какой-то момент он напечатал первый квадрат (что ожидается), но я, должно быть, где-то внес изменение, и теперь кажется, что он печатает только последний.

Любой совет будет оценен. Спасибо!

Ответы [ 3 ]

0 голосов
/ 04 марта 2020

Попробуйте это.

#!/usr/bin/env bash

case $# in
  0) printf 'give me something!' >&2; exit 1;;  ##: If no argument given exit!
esac

sumsq=0 #sum of squares
int=0 #Running sum initialized to 0
count=0 #Running count of numbers passed as arguments

while (( $# )); do
  case $1 in
    *[!0-9]*) printf '%s is not an integer!' >&2 "$1"  ##: If argument is not an int. exit!
      exit 1;;
  esac
  numbers[$((int++))]=$1      #Assigns arguments to integers array increment int by one
  square=$(($1*$1))           #Operation to square argument first arg by itself
  squares[$((int++))]=$square #Square of each argument increment int by one
  sumsq=$((sumsq + square))   #Add square to total
  count=$((count++))          #Increment count
  shift                       #Remove the used argument
done

echo "The squares are ${squares[@]}"
echo "The sum of the squares is $sumsq"
0 голосов
/ 04 марта 2020

Просто перебрать заданные аргументы

#!/bin/bash
for N in "$@"; {          # iterate over args
    squares+=( $((N*N)) ) # will create and then apend array squares
}
sqstr="${squares[@]}"          # create string from array
echo "The squares are $sqstr"  # string of squares will be substituted
echo "The sum of the squares is $((${sqstr// /+}))" # string  will be substituted,
                                                    # spaces  will be changed to +
                                                    # and sum will be calculated

Использование

$ ./test 1 2 3 4 5
The squares are 1 4 9 16 25
The sum of the squares is 55

Обновленная версия

#!/bin/bash
for N do squares+=($((N*N))); done # iterate over args, create and then apend array squares
sqstr="${squares[@]}"              # create string from array
echo "The squares are $sqstr"      # string of squares will be substituted
echo "The sum of the squares is $((${sqstr// /+}))" # string  will be substituted,
                                                    # spaces  will be changed to +
                                                    # and sum will be calculated
0 голосов
/ 04 марта 2020

Легко сделать, просто полностью удалив переменную int и заменив ее на count, которую вы уже увеличиваете в пределах l oop, например,

sumsq=0 #sum of squares
count=0 #Running count of numbers passed as arguments

while (( $# != 0 )); do
    numbers[$count]=$1          #Assigns arguments to integers array
    square=$(($1*$1))           #Operation to square argument first arg by itself
    squares[$count]=$square     #Square of each argument
    sumsq=$((sumsq + square))   #Add square to total
    count=$((count+1))          #Increment count
    shift                       #Remove the used argument
done

Пример использования / Вывод

Внесение изменений выше:

$ bash squares.sh 1 2 3 4
The squares are 1 4 9 16
The sum of the squares is 30

(нет, вы не такие в программировании, это одна из проблем, на которую новые сценаристы могут смотреть часами и не видеть - и почему полезно работать с bash -x scriptname для отладки)


Обновление после комментария Re: Сложность

Выше я только опубликовал необходимые изменения. Если это не работает для вас, то я подозреваю, что где-то опечатка. Вот полный скрипт, который вы можете просто сохранить и запустить:

#!/bin/bash

if [ $# = 0 ]
    then
        echo "Enter some numbers"
    exit 1
fi

sumsq=0 #sum of squares
count=0 #Running count of numbers passed as arguments

while (( $# != 0 )); do
    numbers[$count]=$1          #Assigns arguments to integers array
    square=$(($1*$1))           #Operation to square argument first arg by itself
    squares[$count]=$square     #Square of each argument
    sumsq=$((sumsq + square))   #Add square to total
    count=$((count+1))          #Increment count
    shift                       #Remove the used argument
done

echo "The squares are ${squares[@]}"
echo "The sum of the squares is $sumsq"
exit 0

В соответствии с приведенным выше примером запустите скрипт как:

bash squares.sh 1 2 3 4

(замените squares.sh на любое имя, которое вы дал файл) Если у вас есть какие-либо проблемы, дайте мне знать, потому что это работает довольно хорошо, например,

bash squares.sh 1 2 3 4 5 6 7 8 9
The squares are 1 4 9 16 25 36 49 64 81
The sum of the squares is 285
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...