Итерация по файлам в Bash и получение индекса и количества

Вопрос или проблема

Правильный способ итерации по файлам в каталоге в Bash — использовать “for loop” и шаблон, как показано ниже:

for f in *.jpg; do
    echo "- Обработка файла: $f"
done

Но как я могу получить общее количество файлов и текущий индекс итерации цикла? Мне нужно общее количество, а не кумулятивное количество для отображения прогресса.

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

files=(*.jpg)
total=${#files[@]}
i=0
for f in "${files[@]}"; do
    i=$(( i + 1 ))
    echo индекс $i
    echo всего $total
    echo "- Обработка файла: $f"
done

Объяснение

  • files=(*.jpg): сохранить шаблон в массив $files
  • total=${#files[@]}: прочитать общее количество в $total
  • i=0: инициализировать $i в 0.
  • i=$(( i + 1 )): добавить 1 к $i с каждой итерацией

Это предполагает, что “первая” итерация равна 1. В зависимости от вашего мнения, возможно, вы захотите начать с 0.

Итерация по индексам

Как предложила Ágatha, мы можем итерировать по номерам индексов. Это гораздо проще. То есть:

files=(*.jpg)
total=${#files[@]}
i=0
for i in "${!files[@]}"; do
    echo индекс $i
    echo всего $total
    echo "- Обработка файла: ${files[$i]}"
done

Объяснение

  • ${!files[@]}: это расширяется до индексов, а не до содержимого массива. Таким образом, нам не нужно вручную увеличивать счетчик с помощью i=$(( i + 1 )).
  • echo "- Обработка файла: ${files[$i]}": однако, вместо того чтобы получать имя файла напрямую из цикла, нам нужно вручную ссылаться на него из массива каждый раз.

Примечание: первый индекс здесь равен 0.

Ответ или решение

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

Подход 1: Итерация по массиву файлов

Первый способ — это использование массива для хранения списков файлов с расширением .jpg и дальнейшая итерация по этому массиву. Это позволяет избежать повторного обращения к файловой системе, что повышает производительность.

Вот пример кода:

files=(*.jpg)               # Сохраняем список файлов в массив
total=${#files[@]}          # Получаем общее количество файлов
i=0                         # Инициализируем счетчик

for f in "${files[@]}"; do  # Итерация по массиву
    i=$(( i + 1 ))          # Увеличиваем индекс на 1
    echo "index: $i"        # Выводим текущий индекс
    echo "total: $total"     # Выводим общее количество файлов
    echo "- Обрабатываем файл: $f"  # Выводим имя обрабатываемого файла
done

Объяснение:

  • files=(*.jpg): Сохраняем все файлы с расширением .jpg в массив files.
  • total=${#files[@]}: Получаем общее количество элементов в массиве files.
  • i=0: Инициализируем переменную i, которая будет использоваться как индекс.
  • i=$(( i + 1 )): Увеличиваем индекс i на единицу в каждой итерации цикла.

Подход 2: Итерация по индексам

Другой способ — это итерация непосредственно по индексам массива. Это упрощает код и делает его более лаконичным.

files=(*.jpg)               # Сохраняем список файлов в массив
total=${#files[@]}          # Получаем общее количество файлов

for i in "${!files[@]}"; do  # Итерация по индексам массива
    echo "index: $i"        # Выводим текущий индекс
    echo "total: $total"     # Выводим общее количество файлов
    echo "- Обрабатываем файл: ${files[$i]}"  # Выводим имя обрабатываемого файла
done

Объяснение:

  • ${!files[@]}: Эта конструкция возвращает индексы массива, что позволяет нам не увеличивать счетчик вручную.
  • echo "- Обрабатываем файл: ${files[$i]}": Обращаемся к элементу массива с помощью текущего индекса i.

Примечание

Первый подход начинается с индекса 1, тогда как второй — с индекса 0. Выбор подхода зависит от ваших предпочтений и задачи.

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

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

Капча загружается...