Цикли

Останнє оновлення 2025-11-05 | Редагувати цю сторінку

Приблизний час: 50 хвилин

Огляд

Питання

  • Як виконати одні й ті ж дії над різними файлами?

Цілі

  • Написати цикл, який застосовує одну або декілька команд окремо до кожного файлу в наборі файлів.
  • Простежити, яких значень набуває змінна циклу під час виконання циклу.
  • Пояснити різницю між ім’ям змінної та її значенням.
  • Пояснити, чому в іменах файлів не можна використовувати пробіли та деякі розділові знаки.
  • Продемонструвати, як побачити, які команди були виконані останнім часом.
  • Перезапустити нещодавно виконані команди без повторного введення.

Цикли - це конструкції програмування, які дозволяють повторити команду або набір команд для кожного елемента у списку. Таким чином, автоматизація виконання повторюваних дій суттєво підвищує ефективність. Подібно до шаблонів і автодоповнення, цикли допомагають зменшити кількість вручну набраного тексту (а отже, зменшують кількість помилок).

Припустимо, у нас є кілька сотень файлів даних, які містять інформацію про геноми та мають імена на кшталт basilisk.dat, minotaur.dat та unicorn.dat. Для наступного прикладу ми використаємо каталог exercise-data/creatures, який містить лише три зразкові файли, але ті ж самі методи можна застосувати до значно більшої кількості файлів одночасно.

Ці файли мають однакову структуру: перші три рядки містять назву виду, його класифікацію та дату оновлення, а у наступних рядках наведені послідовності ДНК. Погляньмо, що містять ці файли:

BASH

$ head -n 5 basilisk.dat minotaur.dat unicorn.dat

Для кожного виду ми хотіли б надрукувати його класифікацію, яка наведена у другому рядку відповідного файлу. Для кожного файлу нам потрібно виконати команду head -n 2 і передати її результат через канал до команди tail -n 1. Скористаймося циклом, щоб уникнути цю проблему, але спочатку розгляньмо загальну форму циклу, використовуючи наведений нижче псевдокод:

BASH

# Слово "for" вказує на початок команди для виконання циклу "For"
for thing in list_of_things 
# Слово "do" вказує на початок списку завдань для виконання
do 
    # Відступи всередині циклу не є обов'язковими, але сприяють розбірливості
    operation_using/command $thing 
# Слово "done" вказує на кінець циклу
done  

У такому разі, ми можемо застосувати це до нашого прикладу наступним чином:

BASH

$ for filename in basilisk.dat minotaur.dat unicorn.dat
> do
>     echo $filename
>     head -n 2 $filename | tail -n 1
> done

ВИХІД

basilisk.dat
CLASSIFICATION: basiliscus vulgaris
minotaur.dat
CLASSIFICATION: bos hominus
unicorn.dat
CLASSIFICATION: equus monoceros
Виноска

Слідкуйте за підказками командного рядка

Під час введення нашого циклу запрошення термінала змінювалося з $ на > та назад. Друге запрошення (>) відрізняється, щоб нагадати нам, що ми ще не завершили введення повної команди. Крапка з комою ; використовується для розділення двох команд, написаних в одному рядку.

Коли термінал бачить ключове слово for, він розуміє, що потрібно повторити команду (або групу команд) для кожного елемента зі списку. Кожного разу, коли цикл виконується (цей процес називається ітерацією), елемент списку послідовно присвоюється змінній та виконуються команди всередині циклу, після чого цикл переходить до наступного елементу списку. Усередині циклу ми звертаємося до значення змінної, додаючи $ перед її іменем. Символ $ повідомляє інтерпретатор командного рядка, що далі йде назва змінної, тож слід підставити її значення, а не сприймати запис як текст чи назву команди.

У цьому прикладі список складається з трьох файлів: basilisk.dat, minotaur.dat та unicorn.dat. Кожного разу, коли цикл повторюється, ми спочатку використовуємо echo для друку значення, яке наразі зберігає змінна $filename. Це не обов’язково робити, але допомагає нам слідкувати за виконанням програми. Далі ми виконаємо команду head для файлу, на який зараз посилається $filename. При першому проходженні циклу $filename має значення basilisk.dat. Інтерпретатор виконує команду head над basilisk.dat і передає перші два рядки команді tail, яка виводить другий рядок цього файлу. Для другої ітерації $filename стає minotaur.dat. Цього разу термінал виконує команду head над minotaur.dat і передає перші два рядки команді tail, яка виводить другий рядок minotaur.dat. На третій ітерації $filename стає unicorn.dat, тому термінал виконує команду head для цього файлу, і tail обробляє результат. Оскільки список містив лише три елементи, оболонка закінчує цикл for.

Виноска

Однакові символи, різні значення

Тут ми бачимо, що символ > використовується як запрошення командного рядка, але > також застосовується для перенаправлення виводу. Аналогічно, символ $ діє як запрошення оболонки, але, як ми бачили раніше, його функція теж може полягати в отриманні значення змінної.

Якщо термінал друкує > або $, то він очікує від вас введення команди й цей символ є підказкою.

Якщо ви вводите > або $ самостійно, це означає, що ви даєте команду оболонці перенаправити вивід або отримати значення змінної.

При використанні змінних також можна брати їхні імена у фігурні дужки, щоб чітко відокремити імена змінних: $filename еквівалентно ${filename}, але відрізняється від ${file}name. Ви можете побачити таку форму запису в інших програмах.

Ми назвали змінну у цьому циклі filename (ім’я файлу), щоб її призначення було зрозуміліше для читачів. Самій оболонці байдуже, як називається змінна; якби ми написали цей цикл так:

BASH

$ for x in basilisk.dat minotaur.dat unicorn.dat
> do
>     head -n 2 $x | tail -n 1
> done

або:

BASH

$ for temperature in basilisk.dat minotaur.dat unicorn.dat
> do
>     head -n 2 $temperature | tail -n 1
> done

це спрацювало б точно так само. Але не робіть цього. Програми корисні лише тоді, коли люди можуть їх розуміти, тому беззмістовні (наприклад, x) або оманливі (наприклад, temperature) назви підвищують ймовірність того, що програма поводитиметься не так, як очікують читачі.

У наведених вище прикладах змінним (thing, filename, x та temperature) можна було б призначити будь-які інші імена, аби вони були зрозумілими як автору коду, так і його читачу.

Також майте на увазі, що цикли можна використовувати не лише для імен файлів, а й для списків чисел або підмножини даних.

Вправа

Напишіть свій власний цикл

Як би ви написали цикл, який друкує всі 10 чисел від 0 до 9?

BASH

$ for loop_variable in 0 1 2 3 4 5 6 7 8 9
> do
>     echo $loop_variable
> done

ВИХІД

0
1
2
3
4
5
6
7
8
9
Вправа

Змінні в циклах

Ця вправа стосується каталогу shell-lesson-data/exercise-data/alkanes. Команда ls *.pdb дає такий результат:

ВИХІД

cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb

Що виведе наступний код?

BASH

$ for datafile in *.pdb
> do
>     ls *.pdb
> done

А цей?

BASH

$ for datafile in *.pdb
> do
>     ls $datafile
> done

Чому ці два цикли дають різні результати?

Перший блок коду дає однаковий результат на кожній ітерації циклу. Bash розгортає шаблон *.pdb в тілі циклу (а також перед початком циклу), щоб знайти всі файли, що закінчуються на .pdb, а потім виводить їх список за допомогою ls. Розширений цикл матиме такий вигляд:

BASH

$ for datafile in cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
> do
>     ls cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
> done

ВИХІД

cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb
cubane.pdb  ethane.pdb  methane.pdb  octane.pdb  pentane.pdb  propane.pdb

Другий блок коду працює з іншим файлом під час кожної ітерації циклу. Значення змінної datafile отримується за допомогою $datafile, а потім виводиться командою ls.

ВИХІД

cubane.pdb
ethane.pdb
methane.pdb
octane.pdb
pentane.pdb
propane.pdb
Вправа

Обмеження наборів файлів

Що буде виведено у результаті виконання наступного циклу в каталозі shell-lesson-data/exercise-data/alkanes?

BASH

$ for filename in c*
> do
>     ls $filename
> done
  1. Жодної назви файлу не буде виведено.
  2. Будуть перелічені всі файли.
  3. Будуть перелічені лише cubane.pdb, octane.pdb та pentane.pdb.
  4. Буде виведено лише cubane.pdb.

4 - правильна відповідь. Символ * відповідає нулю або більшій кількості символів, тому будь-яке ім’я файлу, що починається з літери ‘c’, за якою йдуть нуль або більша кількість символів, буде відповідати шаблону c*.

Вправа

Обмеження наборів файлів (continued)

Як зміниться результат, якщо замість цього скористатися ось цією командою?

BASH

$ for filename in *c*
> do
>     ls $filename
> done
  1. Будуть перелічені ті ж самі файли.
  2. Цього разу будуть перелічені всі файли.
  3. Цього разу не буде виведено жодного файлу.
  4. Будуть перелічені файли cubane.pdb та octane.pdb.
  5. Буде перелічено лише файл octane.pdb.

4 - правильна відповідь. Символ * відповідає нулю або більшій кількості символів, тому всі імена файлів з нулем або більшою кількістю символів перед літерою ‘c’ або після літери ‘c’ будуть відповідати шаблону *c*.

Вправа

Як зберігати результати в файл під час виконання циклу - частина перша

В каталозі shell-lesson-data/exercise-data/alkanes, яким буде результат роботи цього циклу?

BASH

for alkanes in *.pdb
do
    echo $alkanes
    cat $alkanes > alkanes.pdb
done
  1. Буде виведено cubane.pdb, ethane.pdb, methane.pdb, octane.pdb, pentane.pdb та propane.pdb, а текст з файлу propane.pdb буде збережено у файлі з назвою alkanes.pdb.
  2. Буде виведено cubane.pdb, ethane.pdb та methane.pdb, а текст з усіх трьох файлів буде об’єднано і збережено у файлі з назвою alkanes.pdb.
  3. Буде виведено cubane.pdb, ethane.pdb, methane.pdb, octane.pdb та pentane.pdb, а текст з файлу propane.pdb буде збережено у файлі з назвою alkanes.pdb.
  4. Жоден із наведених варіантів.
  1. Текст з кожного файлу по черзі буде записуватися у файл alkanes.pdb. Однак, файл буде перезаписуватися на кожній ітерації циклу, тому остаточний вміст alkanes.pdb' буде збігатися з текстом з файлуpropane.pdb`.
Вправа

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

У тому ж каталозі shell-lesson-data/exercise-data/alkanes, що буде виведено у наступному циклі?

BASH

for datafile in *.pdb
do
    cat $datafile >> all.pdb
done
  1. Весь текст з файлів cubane.pdb, ethane.pdb, methane.pdb, octane.pdb та pentane.pdb буде об’єднано і збережено у файлі з назвою all.pdb.
  2. Текст з файлу ethane.pdb буде збережено до файлу з назвою all.pdb.
  3. Весь текст з файлів cubane.pdb, ethane.pdb, methane.pdb, octane.pdb, pentane.pdb та propane.pdb буде об’єднано та збережено у файл з назвою all.pdb.
  4. Весь текст з файлів cubane.pdb, ethane.pdb, methane.pdb, octane.pdb, pentane.pdb та propane.pdb буде виведено на екран і збережено у файлі з назвою all.pdb.

3 - правильна відповідь. Оператор >> додає дані до файлу, а не перезаписує його вміст перенаправленням виводу команди. Оскільки вивід команди cat було перенаправлено, на екран нічого не буде виведено.

Для наступного прикладу перейдемо у каталог shell-lesson-data/exercise-data/creatures. Тут цикл трохи складніший:

BASH

$ for filename in *.dat
> do
>     echo $filename
>     head -n 100 $filename | tail -n 20
> done

Термінал розпочинає роботу з розгортання *.dat, щоб створити список файлів для подальшої обробки. Тіло циклу виконує дві команди для кожного з них. Перша команда, echo, виводить свої аргументи на стандартний вивід (тобто, на standard output). Наприклад:

BASH

$ echo hello there

друкує:

ВИХІД

hello there

У цьому випадку, оскільки термінал підставить до $filename імʼя файлу, echo $filename виведе ім’я файлу. Зауважте, що ми не можемо написати це як:

BASH

$ for filename in *.dat
> do
>     $filename
>     head -n 100 $filename | tail -n 20
> done

тому що під час першої ітерації циклу, коли $filename буде замінено на basilisk.dat, термінал спробує запустити basilisk.dat як програму. Нарешті, комбінація head і tail виділить рядки 81-100 з будь-якого файлу, що наразі обробляється (за умови, що у відповідному файлі є принаймні 100 рядків).

Виноска

Пробіли в іменах

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

red dragon.dat
purple unicorn.dat

Щоб переглянути ці файли у циклі, нам потрібно додати подвійні лапки, ось так:

BASH

$ for filename in "red dragon.dat" "purple unicorn.dat"
> do
>     head -n 100 "$filename" | tail -n 20
> done

Простіше уникати використання пробілів (або інших спеціальних символів) у назвах файлів.

Вищевказані файли не існують, тому під час виконання цього коду команда head не зможе знайти їх; однак у повідомленні про помилку буде вказано, які саме файли вона намагалась відкрити:

ПОМИЛКА

head: cannot open ‘red dragon.dat' for reading: No such file or directory
head: cannot open ‘purple unicorn.dat' for reading: No such file or directory

Спробуйте видалити лапки навколо $filename у наведеному вище циклі, щоб побачити ефект лапок на назвах з пробілами. Зверніть увагу, що ми отримуємо результат команди циклу для unicorn.dat коли ми запускаємо цей код у каталозі creatures:

ВИХІД

head: cannot open ‘red' for reading: No such file or directory
head: cannot open ‘dragon.dat' for reading: No such file or directory
head: cannot open ‘purple' for reading: No such file or directory
CGGTACCGAA
AAGGGTCGCG
CAAGTGTTCC
...

Ми хочемо змінити кожен з файлів у shell-lesson-data/exercise-data/creatures, але при цьому зберегти оригінальні версії файлів. Наприклад, ми хочемо скопіювати оригінальні файли до нових файлів з назвами original-basilisk.dat та original-unicorn.dat. Ми не можемо використати:

BASH

$ cp *.dat original-*.dat

тому що це буде розширено до:

BASH

$ cp basilisk.dat minotaur.dat unicorn.dat original-*.dat

Це не створить резервну копію наших файлів, натомість ми отримаємо помилку:

ПОМИЛКА

cp: target `original-*.dat' is not a directory

Ця проблема виникає, коли команда cp отримує більше ніж два вхідних аргументи. Коли це відбувається, вона очікує, що останнім вхідним параметром буде каталог, куди вона зможе скопіювати всі файли, які їй було передано. Оскільки у каталозі creatures немає каталогу з назвою original-*.dat, ми отримаємо помилку.

Замість цього ми можемо використати цикл:

BASH

$ for filename in *.dat
> do
>     cp $filename original-$filename
> done

Цей цикл виконує команду cp один раз для кожного імені файлу. Перший раз, коли змінна $filename має значення basilisk.dat, термінал виконує:

BASH

cp basilisk.dat original-basilisk.dat

Вдруге, буде виконана наступна команда:

BASH

cp minotaur.dat original-minotaur.dat

В останній раз, команда буде такою:

BASH

cp unicorn.dat original-unicorn.dat

Оскільки команда cp зазвичай не виводить жодного результату, важко перевірити що цикл працює правильно. Однак ми дізналися, як виводити рядки за допомогою echo. Це допоможе нам перевірити, які команди виконувалися б у циклі без їх фактичного виконання.

Наступна діаграма показує, що відбувається при виконанні зміненого циклу, і демонструє, як доречне використання echo може допомагати у програмуванні.

Цикл for "for filename in .dat; do echo cp $filename original-$filename; done" послідовно присвоїть імена всіх ".dat" файлів у вашому поточному каталозі змінній "$filename" та (для кожного значення) виконає команду. Для файлів "basilisk.dat", "minotaur.dat" та "unicorn.dat" в поточному каталозі цикл тричі послідовно викличе команду echo і виведе три рядки: "cp basislisk.dat original-basilisk.dat", потім "cp minotaur.dat original-minotaur.dat" та нарешті "cp unicorn.dat original-unicorn.dat"

Конвеєр Неллі: Обробка файлів


Тепер Неллі готова обробити свої файли даних, використовуючи goostats.sh — скрипт командної оболонки, який був написаний її керівником. Він розраховує деякі статистичні параметри для зразка білка, і приймає два аргументи:

  1. вхідний файл (що містить необроблені дані)
  2. вихідний файл (для збереження обчисленої статистики)

Оскільки вона все ще вчиться користуватися терміналом, вона вирішує будувати потрібну послідовність команд поступово. Спершу потрібно впевнитися, що було обрано правильні вхідні файли — ті, назви яких закінчуються на ‘A’ або ‘B’, але не на ‘Z’. Переходячи до каталогу north-pacific-gyre, Неллі вводить:

BASH

$ cd
$ cd Desktop/shell-lesson-data/north-pacific-gyre
$ for datafile in NENE*A.txt NENE*B.txt
> do
>     echo $datafile
> done

ВИХІД

NENE01729A.txt
NENE01729B.txt
NENE01736A.txt
...
NENE02043A.txt
NENE02043B.txt

Далі треба вирішити як назвати файли, які створюватиме програма аналізу goostats.sh. Додавання префікса ‘stats’ до назви кожного вхідного файлу здається простим рішенням, тому вона модифікує свій цикл відповідним чином:

BASH

$ for datafile in NENE*A.txt NENE*B.txt
> do
>     echo $datafile stats-$datafile
> done

ВИХІД

NENE01729A.txt stats-NENE01729A.txt
NENE01729B.txt stats-NENE01729B.txt
NENE01736A.txt stats-NENE01736A.txt
...
NENE02043A.txt stats-NENE02043A.txt
NENE02043B.txt stats-NENE02043B.txt

Насправді вона ще не запускала goostats.sh, але тепер переконалася, що її скрипт зможе обрати потрібні файли та створити правильні вихідні імена для результатів.

Постійне повторення одних і тих самих команд уже починає набридати, і Неллі боїться помилитися, тому замість цього вона натискає клавішу . У результаті оболонка повторно показує весь цикл в один рядок (використовуючи крапку з комою для розділення його частин):

BASH

$ for datafile in NENE A.txt NENE B.txt; do echo $datafile stats-$datafile; done

Використовуючи , Неллі переходить до команди echo та змінює її на bash goostats.sh:

BASH

$ for datafile in NENE*A.txt NENE*B.txt; do bash goostats.sh $datafile stats-$datafile; done

Коли вона натискає Enter, термінал виконує змінену команду. Однак, здається, нічого не відбувається — немає жодного виводу. Через деякий час Неллі розуміє, що оскільки її скрипт більше нічого не виводить на екран, вона не має жодного уявлення як швидко він виконується і чи працює взагалі. Вона перериває виконання команди, натискаючи Ctrl+C, та за допомогою клавіші повторно викликає її та редагує, щоб вона виглядала так:

BASH

$ for datafile in NENE*A.txt NENE*B.txt; do echo $datafile;
bash goostats.sh $datafile stats-$datafile; done
Виноска

Початок і кінець рядка

Щоб швидко переміститися на початок рядка в терміналі, натисніть Ctrl+A, а щоб перейти в його кінець — Ctrl+E.

Тепер, коли Неллі запускає свою програму, та виводить один рядок приблизно кожні п’ять секунд:

ВИХІД

NENE01729A.txt
NENE01736A.txt
NENE01751A.txt
...

Помножив 1518 файлів на 5 секунд і поділивши результат на 60, Неллі підраховує що її скрипт буде виконуватися близько двох годин. Для завершення перевірки вона відкриває нове вікно терміналу, переходить до каталогу north-pacific-gyre та використовує команду cat stats-NENE01729B.txt. для перегляду одного зі створених файлів. Оскільки все працює як слід, Неллі задоволено йде зробити каву та провести час із книжкою.

Виноска

Хто знає історію, той може її повторити

Ще один спосіб відтворити попередні дії — це команда history, яка показує перелік останніх кількох сотень виконаних команд. Після цього можна ввести !123 (де ‘123’ замінено на номер відповідної команди), щоб запустити її знову. Наприклад, якщо Неллі набере наступне:

BASH

$ history | tail -n 5

ВИХІД

456  for datafile in NENE*A.txt NENE*B.txt; do   echo $datafile stats-$datafile; done
457  for datafile in NENE*A.txt NENE*B.txt; do echo $datafile stats-$datafile; done
458  for datafile in NENE*A.txt NENE*B.txt; do bash goostats.sh $datafile stats-$datafile; done
459  for datafile in NENE*A.txt NENE*B.txt; do echo $datafile; bash goostats.sh $datafile
stats-$datafile; done
460  history | tail -n 5

то вона може перезапустити goostats.sh просто набравши !459.

Виноска

Інші корисні команди для роботи з історією

Окрім history, існує низка скорочень, які дозволяють швидше переглядати та викликати попередні команди.

  • Ctrl+R переходить у режим ‘зворотного пошуку’, який дозволяє знайти останню команду завдяки частині тексту. Натисніть Ctrl+R ще один або кілька разів для перегляду більш ранніх збігів. Після цього можна за допомогою стрілок вліво та вправо переміститися по знайденому рядку, відредагувати його та натиснути Return, щоб виконати команду.
  • !! повертає безпосередньо попередню команду (деякі з вас можуть знайти це більш зручним, ніж використання )
  • !$ повертає останнє слово останньої команди. Ця можливість корисна частіше, ніж здається: після bash goostats.sh NENE01729B.txt stats-NENE01729B.txt можна просто набрати less !$ для перегляду файлу stats-NENE01729B.txt, що швидше, ніж шукати попередню команду зі та змінювати її вручну.
Вправа

Пробний запуск

Цикл — це спосіб виконати багато дій одночасно — або зробити багато помилок одразу, якщо він робить щось не те. Один зі способів перевірити роботу циклу - замінити фактичне виконання команд на echo.

Припустимо, ми хочемо переглянути команди, які виконає наступний цикл, без виконання цих команд:

BASH

$ for datafile in *.pdb
> do
>     cat $datafile >> all.pdb
> done

У чому різниця між двома наведеними нижче циклами, і який із них слід запустити?

BASH

# Варіант 1
$ for datafile in *.pdb
> do
>     echo cat $datafile >> all.pdb
> done

BASH

# Варіант 2
$ for datafile in *.pdb
> do
>     echo "cat $datafile >> all.pdb"
> done

Нам потрібен саме другий варіант циклу. Він виводить на екран увесь текст у лапках, підставивши назву змінної циклу, оскільки перед нею стоїть знак долара. Крім того, ця команда не створює і не змінює файл all.pdb, оскільки оператор >> розглядається як частина рядка, а не як інструкція перенаправлення виводу.

Перша версія додає вивід команди echo cat $datafile до файлу all.pdb. Цей файл міститиме лише список команд типу cat cubane.pdb, cat ethane.pdb, cat methane.pdb тощо.

Спробуйте обидві версії самостійно, щоб побачити результат! Обов’язково відкрийте файл all.pdb, щоб переглянути його вміст.

Вправа

Вкладені цикли

Припустімо, що ми хочемо створити систему каталогів для впорядкування певних експериментів, у яких досліджується швидкість реакцій із різними хімічними сполуками та температурами. Яким буде результат виконання наступного коду:

BASH

$ for species in cubane ethane methane
> do
>     for temperature in 25 30 37 40
>     do
>         mkdir $species-$temperature
>     done
> done

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

Спробуйте запустити цей код самостійно, щоб побачити, які каталоги буде створено!

Ключові моменти
  • Цикл for повторює команди один раз для кожного елемента списку.
  • У кожному циклі for використовується змінна, що вказує на поточний об’єкт, з яким він зараз працює.
  • Використовуйте $name для підстановки змінної (тобто отримання її значення). Також можна використовувати ${name}.
  • Не варто використовувати пробіли, лапки чи символи підстановки, такі як ‘*’ або ‘?’, у назвах файлів, адже це може призвести до помилок під час роботи зі змінними.
  • Надавайте файлам послідовні імена, які можна легко описати за допомогою шаблонів, щоб полегшити їх вибір для циклів.
  • Щоб швидко знайти й повторити попередню команду, скористайтеся клавішею зі стрілкою вгору — це дозволяє редагувати та виконувати її без повторного введення.
  • Використовуйте Ctrl+R для пошуку попередньо введених команд.
  • Використовуйте команду history, щоб побачити перелік останніх команд; також застосовуйте ![номер] для повторення команди за її номером.