Добавление групп изображений на основе их общего размера

Я используюpam-tmpdirдля этого :он создает пользовательский -личный временный каталог при входе в систему. Чтобы настроить его, добавьте

session optional pam_tmpdir.so

к соответствующим службам PAM; в системе на основе Debian -установка пакета libpam-tmpdirпредложит сделать это за вас, или вы можете добавить строку в /etc/pam.d/common-session. В следующий раз, когда вы войдете в систему, вы найдете каталог под /tmp/userс вашим идентификатором пользователя, а TMPи TMPDIRнастроены соответствующим образом.

0
08.05.2020, 14:18
2 ответа

Если вам нужно, чтобы ваши пакетные -добавленные изображения оказывались внутри объектов размером менее 950 КБ, то ни один файл изображения не может иметь размер, превышающий тот же предельный размер.
Первый шаг:список всех таких файлов вместе с их размером в байтах:

$ find -L /path/to/directory -maxdepth 1 -type f -name "*.gif" -size -950k \
 -exec sh -c '\ls -Lgo "$1" | tr -s " "  | cut "-d " -f3,7-' sh {} \;

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

  • -L:переходите по символическим ссылкам и предоставляете информацию о цели ссылки, а не о самой ссылке. Если вы этого не хотите, используйте вместо этого -H.
  • -maxdepth 1:поиск спускается не более чем на1уровень вниз от /path/to/directory. Измените номер по своему усмотрению. См. man findдля получения дополнительной информации.

Обратите внимание, что, по крайней мере, в моей реализации bash5.0 findработает с кибибайтами (киБ ). Другими словами, описанное выше найдет файлы, размер которых меньше или равен 950 *1024 байт. Если вы настаиваете на том, чтобы 950 килобайт (950000 B )были вашим предельным размером,нет проблем :просто используйте вместо этого -size 927730c. В дистрибутивах Debian это, кажется, было решено еще в 2016 году, поэтому вы можете продолжить и использовать -size 950k...

«Размер» может быть неоднозначным свойством. Из-за отсутствия дополнительной информации в OP я также включаю тот факт, что вы можете использовать общий выделенный размер блока для каждого обнаруженного файла. Если это то, что вы хотите/нужно, то сделайте:

$ find -L /path/to/directory -maxdepth 1 -type f -name "*.gif" -size -950k \
  -exec sh -c '\ls -Ls -C1 "$1"' sh {} \;

Цифры размера, которые вы получите, будут зависеть от размера блока вашего носителя данных.

Второй шаг:— обработка предыдущего вывода с помощью magickпосредством сценария оболочки batch_append.shза один проход. Добавляйте файлы изображений в указанном порядке, при условии, что ни один полученный объект не должен весить более 950 КБ. Вывод команды findиспользуется для заполнения такого массива:

$ cat batch_append.sh

#!/usr/bin/bash

sdir=/path/to/directory
size=0
nas_idx=0    # next append start (nas) index (idx)
cnt=0
declare -a b

IFS=$'\n' read -d '' -a a < <(find -L "$sdir" -maxdepth 1 -type f -name "*.gif" -size -950k -exec sh -c '\ls -Lgo "$1" | tr -s " " | cut "-d " -f3,7-' sh {} \; 2>/dev/null)
num=${#a[@]}

for (( i=0; i<num; i++ )); do
    (( size+=$(echo "${a[$i]}" | cut "-d " -f1) ))

    if [ "$size" -gt 950000 ] ; then
        (( size-=$(echo "${a[$i]}" | cut "-d " -f1) ))
        (( i-=1 ))
        #echo "$size" for files from "$(( nas_idx+1 ))" to "$(( i+1 ))"  # testing
        #echo "${b[@]}"   # testing
        magick "${b[@]}" append appended_$(( nas_idx+1 ))_$(( i+1 )).gif
        nas_idx=$(( i+1 ))
        size=0  # reset 'size' variable to start new append batch
        cnt=0
        unset b
    else
        b[cnt]=$(echo "${a[$i]}" | cut "-d " -f2-)
        (( cnt++ ))
    fi

    if (( i==num-1 )); then
        # last append batch
        #echo "$size" for files from "$(( nas_idx+1 ))" to "$(( i+1 ))"  # testing
        #echo "${b[@]}"   # testing
        magick "${b[@]}" append appended_$(( nas_idx+1 ))_$(( i+1 )).gif
        unset b
    fi
done

printf '\n  %d files were processed.\n' "$num"
exit(0)

Заключительные замечания:

  • Сделайте скрипт исполняемым перед его запуском.chmod ug+x batch_append.sh
  • Скрипт необходимо запустить только один раз.
  • Этот сценарий не был полностью протестирован с magick.
  • Для производственной среды следует включить ряд ловушек.
  • Сценарий можно улучшить, возможно, организовав параллельное выполнение, если у вашего хоста несколько ядер и много файлов для обработки.
  • Файлы обрабатываются пакетно -по мере их поступления, т. е. по мере их статистики findcmd. Это будет зависеть от количества поисковых флажков и от того, как вы заказываете findодин -вкладыш.
-1
28.04.2021, 23:15

Хорошо, я почти уверен, что это самый крутой лайнер, с которым я когда-либо сталкивался, но я думаю, что он сделает это. Вольно основано наhttps://askubuntu.com/questions/878948/how-do-i-generate-a-running-cumulative-total-of-the-numbers-in-a-text-file

sed $(echo 3+`ls -la | tee out/filesWithSizes.txt | awk '{print $5}' | awk '{total += $0; $0 = total}1' | sed 's/$/ < 950000/' | bc | grep -o '1' | wc -l`|bc )q out/filesWithSizes.txt | tail -n +4

Позвольте мне объяснить это безумие:

Используйте ls -la, чтобы получить все файлы с их размерами

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

Используйте awkдля печати 5-го столбца (, т.е. размера)

Используйте больше awk, чтобы сгенерировать кумулятивную сумму, которая гарантированно будет отсортирована для каждого проекта (, что станет важным позже)

Используйте sed, чтобы заменить конец строки на < 950000, чтобы добавить эту строку

Используйте bcдля вычисления этих выражений и преобразования их в логические значения (, т.е. 0 или 1)

Используйте grep -oдля печати только строк с 1

поскольку совокупная сумма сортируется по дизайну, ее вывод можно подсчитать, и вы знаете количество файлов (по порядку ), которые можно склеить вместе

Эта часть выполняется с помощью wc -l. Поскольку я не заработал без флага a в начальном ls, я повторяю 3+число --, мы -просто -вычисляем в bc, чтобы получить точку остановки для вывода списка файлов

Затем используйте sedс подстановкой команд, чтобы прекратить вывод содержимого списка файлов с их размерами, которые мы сохранили ранее, после того количества строк, которое мы только что вычислили с помощью этого эха

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

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

-1
28.04.2021, 23:15

Теги

Похожие вопросы