Работа с файлами в каталоге при помощи циклов

Не все утилиты командной строки позволяют запускать одну команду для нескольких файлов одновременно, но с помощью сценариев оболочки и цикла for вы можете автоматически повторить любую команду.

Цикл – один из самых мощных аспектов в программировании. Он позволяет вам многократно применять одну и ту же логику к группе элементов, требуя при этом минимального количества кода.

В этом мануале мы научим вас перебирать файлы и применять команды с помощью оболочки Bash или zsh.

1: Перебор файлов

В этом мануале мы будем использовать цикл сценариев для оболочки. Этот конкретный метод управления встроен в оболочку командной строки Bash или zsh.

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

Сначала создайте каталог:

mkdir looping

Затем перейдите в него:

cd looping

С помощью команды touch создайте несколько текстовых файлов:

touch file-1.txt
touch file-2.txt
touch file-3.txt
touch file-4.txt
touch file-5.txt

Вы также можете быстро создать эти файлы, задав диапазон в скобках:

touch file-{1..5}.txt

Чтобы просмотреть каталог и затем вывести имя файла, выполните следующую команду:

for FILE in *; do echo $FILE; done

Вы увидите следующий результат:

file-1.txt
file-2.txt
file-3.txt
file-4.txt
file-5.txt

Вы, наверное, заметили, что здесь используется подстановочный знак *. Он позволяет циклу for захватить каждый файл в каталоге. Вы можете изменить подстановочный знак на file-*, чтобы вывести все файлы, имена которых начинаются с file-, или на *.txt, чтобы вывести только текстовые файлы.

Теперь, когда вы знаете, как перебирать файлы в каталоге, давайте применим команду к этим файлам.

2: Применение команды

Все файлы, которые вы создали в предыдущем разделе, были созданы с помощью команды touch. Эти файлы пусты, поэтому применять к ним команду cat было бы не очень полезно.

К счастью, вы можете вставить текст в каждый файл с помощью одной команды, используя аналогичный цикл for.

Выполните следующую команду, чтобы вставить имя файла, новую строку и текст «Loops Rule!» в каждый файл:

for FILE in *; do echo -e "$FILE\nLoops Rule\!" > $FILE; done

Флаг -e в команде echo гарантирует сохранение новых строк.

Восклицательный знак нужно избежать с помощью обратного слеша, чтобы оболочка не интерпретировала символ как команду оболочки.

Теперь переберите каждый файл и выведите его содержимое:

for FILE in *; do cat $FILE; done

Теперь каждый файл содержит имя файла в первой строке и сообщение о том, что циклы классные, во второй строке.

file-1.txt
Loops Rule!
file-2.txt
Loops Rule!
file-3.txt
Loops Rule!
file-4.txt
Loops Rule!
file-5.txt
Loops Rule!

Дальше мы попробуем объединить эти примеры: сначала записать данные в файл, а затем отобразить его содержимое в одном цикле:

for FILE in *; do echo -e "$FILE\nLoops Rule\!" > $FILE; cat $FILE; done

Вы увидите следующий результат:

file-1.txt
Loops Rule!
file-2.txt
Loops Rule!
file-3.txt
Loops Rule!
file-4.txt
Loops Rule!
file-5.txt
Loops Rule!

При помощи точки с запятой (;) вы можете связать вместе любые необходимые команды.

Теперь давайте рассмотрим практический пример: создание резервных копий файлов.

3: Создание резервных копий файлов

Теперь, когда вы знаете, как работает цикл for, давайте попробуем сделать что-то полезное: возьмем каталог файлов и сделаем резервные копии с расширением .bak.

Выполните в своей оболочке следующую команду, которая создает резервную копию для каждого файла:

for FILE in *; do cp $FILE "$FILE.bak"; done;

С помощью команды ls отобразите все файлы:

ls -l

Вы увидите такой результат:

total 40K
-rw-r--r-- 1 8host 8host 29 Nov  7 18:34 file-1.txt
-rw-r--r-- 1 8host 8host 29 Nov  7 18:41 file-1.txt.bak
-rw-r--r-- 1 8host 8host 29 Nov  7 18:34 file-2.txt
-rw-r--r-- 1 8host 8host 29 Nov  7 18:41 file-2.txt.bak
-rw-r--r-- 1 8host 8host 29 Nov  7 18:34 file-3.txt
-rw-r--r-- 1 8host 8host 29 Nov  7 18:41 file-3.txt.bak
-rw-r--r-- 1 8host 8host 29 Nov  7 18:34 file-4.txt
-rw-r--r-- 1 8host 8host 29 Nov  7 18:41 file-4.txt.bak
-rw-r--r-- 1 8host 8host 29 Nov  7 18:34 file-5.txt
-rw-r--r-- 1 8host 8host 29 Nov  7 18:41 file-5.txt.bak

Теперь у вас есть резервные копии всех ваших файлов. Их расширение указывает, что это резервные копии.

Создание копий в одном каталоге – это далеко не единственная задача, которую вы можете выполнить с помощью цикла. Вы можете также указать новый путь для файлов резервных копий. Следующая команда сохраняет резервные копии в папке /tmp/my-backups (если указанный каталог уже существует):

for FILE in *; do cp $FILE "/tmp/my-backups/$FILE.bak"; done;

Резервные копии будут созданы в новом каталоге.

Заключение

В этом мануале мы поэкспериментировали с циклом for и научились использовать его для перебора файлов и применения команд к нескольким фалам в каталоге.

Добавить комментарий