Як написати цикл for у bash


Відповіді:


103

З цього сайту :

for i in $(seq 1 10);
do
    echo $i
done

10
Варто зазначити, що вказаний тут діапазон включно . Під цим я маю на увазі, що ви побачите весь діапазон (від 1 до 10), надрукований на консолі.
Джеймі


34

Баш forскладається із змінної (ітератора) та списку слів, де ітератор буде, ну, повторювати.

Отже, якщо у вас обмежений перелік слів, просто вкажіть їх у наступному синтаксисі:

for w in word1 word2 word3
do
  doSomething($w)
done

Ймовірно, ви хочете повторити кілька чисел, тому ви можете скористатися seqкомандою, щоб створити для вас список чисел: (наприклад, від 1 до 100)

seq 1 100

і використовувати його в циклі FOR:

for n in $(seq 1 100)
do
  doSomething($n)
done

Зверніть увагу на $(...)синтаксис. Це поведінка bash, вона дозволяє передавати вихідні дані однієї команди (у нашому випадку з seq) іншій (the for)

Це дуже корисно, коли вам доведеться переглядати всі каталоги на якомусь шляху, наприклад:

for d in $(find $somepath -type d)
do
  doSomething($d)
done

Можливості створення списків нескінченні.


2
Хороша відповідь, але ви можете включити for ((i = 0; i <MAX; i ++)); do doSomething ($ i); готовий варіант. Я думаю, що це, як правило, кращий варіант for i у $ (seq 0 MAX), оскільки останній спочатку генерує всі числа від 0 до MAX до фактичного виконання циклу.
mweerden

30

Bash 3.0+ може використовувати такий синтаксис:

for i in {1..10} ; do ... ; done

..котрий дозволяє уникнути появи зовнішньої програми для розширення послідовності (наприклад seq 1 10).

Звичайно, це має ту ж проблему, що і for(())рішення, пов’язане з bash і навіть певною версією (якщо це для вас важливо).


14

Спробуйте bashвбудовану допомогу:


$ help for

for: for NAME [in WORDS ... ;] do COMMANDS; done
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Equivalent to
        (( EXP1 ))
        while (( EXP2 )); do
            COMMANDS
            (( EXP3 ))
        done
    EXP1, EXP2, and EXP3 are arithmetic expressions.  If any expression is
    omitted, it behaves as if it evaluates to 1.


5
#! /bin/bash

function do_something {
   echo value=${1}
}

MAX=4
for (( i=0; i<MAX; i++ )) ; {
   do_something ${i}
}

Ось приклад, який також може працювати у старих оболонках, але при цьому залишається ефективним для великих відліків:

Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'

Але удачі в корисних справах всередині awk: Як я використовую змінні оболонки в сценарії awk?


2
Раніше я цього не помічав, але подібний синтаксис показаний в одній із попередніх відповідей. Унікальність тут полягає у використанні фігурних дужок замість типових do/ doneпари.
Брент Бредберн,

4

Я зазвичай люблю використовувати невеликий варіант стандартного циклу for. Я часто використовую це для запуску команди на ряд віддалених хостів. Я використовую перевагу розширення фігурних дужок bash для створення циклів, які дозволяють мені створювати нечислові цикли for-loop.

Приклад:

Я хочу запустити команду uptime на хостах frontend 1-5 та вхідних хостів 1-3:

% for host in {frontend{1..5},backend{1..3}}.mycompany.com
    do ssh $host "echo -n $host; uptime"
  done

Зазвичай я запускаю це як однорядкову команду з крапкою з комою на кінцях рядків замість більш читабельної версії вище. Основне врахування використання полягає в тому, що дужки дозволяють задавати декілька значень, які потрібно вставити в рядок (наприклад, до {foo, bar} публікація результатів у префопості, пребарпоста) та дозволяють рахувати / послідовності, використовуючи подвійні періоди (можна використовувати a. .z тощо). Однак синтаксис подвійного періоду - нова особливість bash 3.0; попередні версії цього не підтримуватимуть.


З цим пов'язано, що робити, якщо $ хост var є порожнім рядком через випадкові випадки? Це все одно вистрілив ssh. Отже, як мені цього уникнути? У моєму випадку я роблю щось інше, тому ваша відповідь допоможе мені. Я намагаюся перевірити Gmail на наявність нових повідомлень і, якщо вони знайдені, надішліть SMS від та теми. Моє запитання має назву «Підключення двох команд Bash», якщо ви хочете його прочитати.
Volomike

Я не вірю, що ви отримаєте порожній $ хост-вар. Це тому, що в наведеному вище прикладі використовується розширення дужок. Цикл for явно встановлює для змінної $ host значення: frontend1.mycompany.com frontend2.mycompany.com. . backend1.mycompany.com Але якщо ви бачите спосіб мати нульове значення; Мені було б цікаво знати. Ви можете виконати ssh всередині умовного тесту, якби це викликало занепокоєння.
Терсон

1

якщо вас цікавить лише bash, найкраще представлене вище рішення "for ((...))", але якщо ви хочете щось сумісне з POSIX SH, що працюватиме на всіх UNIX, вам доведеться використовувати "expr" та "while", і це тому, що "(())" або "seq" або "i = i + 1" не є таким портативним серед різних оболонок


0

Я весь час використовую варіанти цього для обробки файлів ...

для файлів у * .log; do echo "Роби речі з: $ файлами"; echo "Зробити більше речей з: $ файлами"; зроблено;

Якщо вас цікавить обробка списків файлів, зверніться до опції -execdir для файлів .


Думаю, ви маєте на увазі варіант -execdir для пошуку
Призупинено до подальшого повідомлення.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.