Получить имя каталога и файлы внутри каталогов в одном выводе.

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

У меня есть структура директорий следующего вида:

dir1/
    732842342.mp4
    screenshot1.png
dir2/
    324324234.mp4
    screenshot2.png
dir3/
    121321321.mp4
    screenshot3.png

Я пытаюсь создать CSV файл следующего формата:

dir_name, video_name, screenshot_file
dir1, 732842342.mp4, screenshot1.png
dir2, 324324234.mp4, screenshot2.png
dir3, 121321321.mp4, screenshot3.png

Я могу получить имя каждой директории, просто запустив ls

$ ls
dir1
dir2
dir3

Я не знаю, как выполнить следующий шаг, так как это потребует перехода в каждую директорию (например cd dir1/ && ls), а затем получения имени файлов .mp4 и .png. Однако это отдельная команда от первой, поэтому имя директории (dir1 в этом случае) не сохраняется в выводе, так как используются 2 отдельные команды.

Хотелось бы написать перезапускаемый bash-скрипт для этой задачи, но я не уверен в синтаксисе. Кто-нибудь может помочь?

Используй find и sed

Сначала создайте выходной файл и строку с заголовками

echo "dir_name, video_name, screenshot_file" > myfile.csv

find dir* -print | sed 's!/!, !g'| sed 's!^.,!!' >> myfile.csv

Команда find выводит содержимое директорий, начинающихся с ‘dir’.

Первая команда sed заменяет слеш на запятую и пробел. ‘g’ гарантирует, что это произойдет для каждого совпадения.

Вторая команда sed сопоставляет точку и запятую в начале каждой строки и заменяет их ничем.

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

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

Вопрос, касающийся генерации CSV файла с информацией о директориях и файлах в них, может показаться сложным, но с помощью инструментов Unix, таких как find и sed, можно не только решить эту задачу, но и сделать процесс автоматическим и повторяемым с помощью Bash-скрипта. Давайте разберемся подробнее, как этого можно достичь.

Теория (Theory)

Для решения задачи необходимо понять структуру директории и формат выходного файла, которые требуется получить. Структура директории представлена тремя папками (dir1, dir2, dir3), каждая из которых содержит файл с расширением .mp4 и другой с расширением .png. Необходимо создать CSV файл, содержащий строки, где каждая строка представляет отдельную директорию и имеет формат:

dir_name, video_name, screenshot_file
dir1, 732842342.mp4, screenshot1.png

Для этого можно использовать find, чтобы рекурсивно просканировать все директории, и sed для форматирования вывода в CSV файл.

Пример (Example)

  1. Создание заголовка в файле CSV:

    Начнем с создания файла CSV и добавления в него заголовка:

    echo "dir_name, video_name, screenshot_file" > myfile.csv
  2. Использование find и sed:

    Команду find можно использовать для поиска файлов в директориях, начиная с имен на "dir". После этого sed может быть использован для замены слэшей на запятые и пробелы, а также для удаления ненужных символов.

    find dir* -type f -print | sed 's!/!, !g' | sed 's!^.,!!' >> myfile.csv
    • find dir* -type f -print: Печатает все файлы в директориях, в именах которых присутствует "dir".
    • Первый sed: Заменяет слэши на запятые и пробелы для более удобного форматирования.
    • Второй sed: Удаляет точку и запятую, если они присутствуют в начале строки.
  3. Обработка вывода для CSV:

    Обработка вывода команд обеспечивает, что каждая строка в CSV файле будет содержать название директории, за которым следует имя видеозаписи и имя файла-скриншота.

Применение (Application)

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

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

for dir in dir*/; do
    video=$(find "$dir" -maxdepth 1 -type f -name '*.mp4' | head -n 1)
    screenshot=$(find "$dir" -maxdepth 1 -type f -name '*.png' | head -n 1)
    if [[ -z "$video" || -z "$screenshot" ]]; then
        echo "Warning: $dir is missing either video or screenshot file"
        continue
    fi
    echo "$(basename "$dir"), $(basename "$video"), $(basename "$screenshot")" >> myfile.csv
done

Этот кусок кода добавляет дополнительные проверки, но в общем виде сохраняет функциональность, создавая CSV файл с необходимой структурой.

Заключение

Использование инструментов командной строки Unix позволяет эффективно обрабатывать большие объемы данных и формировать отчеты в нужном формате. Этот подход демонстрирует, как можно использовать комбинацию find и sed для автоматизации задач с обработкой файлов. Тем не менее, для полного учета всех возможных проблем стоит добавить больше проверок и, возможно, расширить функционал скрипта в сторону более больших и сложных сценариев использования.

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

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