Хобрук: Ваш путь к мастерству в программировании

Как переписать цикл bash «пока» как цикл «для»?

Это мой код сценария bash, поэтому я хочу знать, как переписать приведенный ниже сценарий Bash, используя цикл «for» вместо цикла «пока».

  #!/bin/bash
    if [ $# -gt 0 ]; then                
           a=0;                
           if [ -f RandNos ]; then
               rm RandNos;
           fi

           while [ $a -lt $1 ]
           do
               a='expr $a + 1';
               myrand=$RANDOM;

              if [ "$2" "1"]; then
                  echo "No. $a ==> $myrand";
              fi

              echo $myrand>>RandNos
           done                
    else 
        echo "please use with an argument..."
    fi

Спасибо.

12.07.2014


Ответы:


1

Простое переписывание с помощью цикла for приводит к следующему результату:

#!/bin/bash
if [ $# -gt 0 ]; then
   if [ -f RandNos ]; then
      rm RandNos;
   fi
   lim=$(expr $1 - 1)
   as=$(seq 0 $lim)
   for a in $as
   do
      a='expr $a + 1';
      myrand=$RANDOM;
      if [ "$2" "1"]; then  # <- Caveat: conditional is BROKEN
         echo "No. $a ==> $myrand";
      fi
      echo $myrand>>RandNos
   done
else 
   echo "please use with an argument..."
fi

Но в любом случае со сценарием что-то не так. Как и последний оператор if.

12.07.2014

2

Кратко: для циклов на основе счетчиков используйте C-подобную форму цикла for:

    for (( a = 0; a < $1; a++ )); do
        # ... use $a
    done

(Это заменяет while [ $a -lt $1 ]; do a='expr $a + 1' ...; done.)

Подробнее о правилах, которые применяются внутри (( ... )), см. ниже.


Что касается остального кода:

  • Conditional [ "$2" "1"] is broken: it's missing the mandatory space before ]
    • With that fixed, it'll only work if $2 expands to a unary test operator such as -n.
    • Возможно, вы имели в виду if [[ -z $myrand ]]; then, чтобы проверить, не привело ли $RANDOM к непустой строке?
  • a='expr $a + 1' — который вам больше не нужен с циклом for — на самом деле не вызывает expr, потому что вы используете одинарные кавычки — вам понадобятся обратные кавычки (` ) или, что предпочтительнее, современный эквивалент: $(expr $a + 1). Однако с помощью арифметической оценки это можно упростить до (( ++a )).

  • Условные выражения [ ... ] работают в bash, но они предусмотрены для совместимости с POSIX — используйте [[ ... ]] в качестве альтернативы для bash, которая более надежна, имеет больше возможностей и работает быстрее.

  • команды bash должны заканчиваться ; только в том случае, если вы помещаете несколько в одну строку

    • Note that bash considers do ... and then ... separate statements, hence you often see if ...; then and for ...; do.

Обратите внимание, что внутри (( ... )) применяются различные правила по сравнению с другими местами в bash:

  • пробелы вокруг = в назначении переменной разрешены.
  • ссылка на переменную без префикса $ (a++) разрешена.
  • < выполняет числовое сравнение (тогда как внутри [[ ... ]] оно лексическое), то есть это более естественный эквивалент -lt внутри [ ... ] или [[ ... ]].
  • поддерживаются несколько других математических и даже побитовых операторов
  • ...

Все эти различные правила применяются, когда bash работает в арифметическом контексте, который применяется к (( ... )), $(( ... )), индексам массива и другим случаям.
Чтобы узнать все правила, запустите man bash и прочитайте раздел ARITHMETIC EVALUATION.

12.07.2014

3

Несколько вещей можно улучшить:

#!/bin/bash
if (( $# )); then                              # anything but 0 is true
   rm -f RandNos                            # remove if existing, otherwise fail silently
   for ((a=0; a<$1; a++)); do
      myrand=$RANDOM

#  what is the intention here?
      (( $2 > 1 )) && echo "No. $a ==> $myrand"
      echo "$myrand" >> RandNos
   done
else
   echo "please use with an argument..."
fi

не уверен, каково ваше намерение с выражением [ "$2" "1" ]. это, вероятно, не то, что я сделал из него.

for ((a=1; a<=$1; a++)); do

может лучше отражать вашу предполагаемую логику, поскольку вы используете $a для вывода только после его увеличения. как указано и исправлено @mklement0

12.07.2014
  • ((a=0; a<$1; a++)) и ((a=0; a<$1; ++a)) одинаковы: внутри цикла $a начинается с 0 в любом случае, а $a увеличивается только после каждой итерации - другими словами: это не имеет значения используете ли вы пре- или постинкремент. Если вы действительно хотите начать с 1, используйте ((a=1; a<=$1; a++)). 13.07.2014

  • 4

    !/бин/баш

    if [ $# -gt 0 ]; then
    
    a=0;
        if [ -f RandNos ]; then
            rm RandNos;
        fi
        for (( i=$a; i<$1; i++ ))
    
        do
       
        myrand=$RANDOM;
        if [ "$2" = "1" ]; then
            echo "No. $a ==> $myrand";
        fi
        echo $myrand >> RandNos
        done
    else
        echo "please use with an argument..."
    fi
    
    13.07.2014
    Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..


    © 2024 hobruk.ru, Хобрук: Ваш путь к мастерству в программировании