Покажите сумму размеров файла в списке каталогов

Параллель GNU делает это и больше (использующий ssh).

Это может даже иметь дело со смешанной скоростью машин, поскольку это просто имеет очередь заданий, которые запускаются в списке машин (например, один на ядро процессора). Когда концы заданий другой запускается.

Таким образом, это не делит задания на кластеры перед запуском, но делает это динамично.

Посмотрите вводные видео для узнавания больше: http://pi.dk/1

78
13.04.2017, 15:36
13 ответов

Следующая функция делает большую часть того, что Вы просите:

dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }

... но это не даст Вам, что Вы просите от dir -R *.jpg *.tif, потому что это не то, как ls -R работы. Вы могли бы хотеть играть вокруг с find утилита для этого.

24
27.01.2020, 19:31
  • 1
    Это верно при поиске по существу размера содержания каждого файла, НЕ размера, файл использует на диске. Это различие является более явным для очень маленьких файлов. На каждом файле моего дистрибутива выделенное место на диске в блоках на 4 КБ (таким образом, 300-байтовый файл все еще использует 4K на диске, как сообщается командой du). Учитывая это - то, что искал OP, "сколько пространства каждый файл поднимает", затем du является способом сделать это. –  Jon V 10.01.2017, 22:20
  • 2
    dir уже название популярного GNU coreutil, я не назвал бы функцию как этот. –  dessert 03.11.2017, 10:18

Уже существует команда UNIX для этого: du

Просто сделайте:

du -ach 

Согласно конвенции можно добавить один или несколько путей файла или каталога в конце команды. -h расширение должно преобразовать размер в человечески-благоприятный формат, -a дает Вам "очевидный" размер (размер файла вместо использования диска), и -c дает общее количество в конце.

157
27.01.2020, 19:31
  • 1
    . Можно использовать-c опцию (то же как - общее количество) для получения общего количества в конце списка. –  MikeB 21.05.2014, 19:28
  • 2
    Отметьте это du дает использование диска, не сумму размеров файла. –  Stéphane Chazelas 09.02.2015, 12:41
  • 3
    du -h не суммирует размеры файлов, переданных ему. du -h *.so показывает размер каждого файла, но не сумму. Я думаю, что Вы желаете, вот du -hc *.so (или даже du -hc *.so | tail -1). Но конечно, он хочет список каталогов, также. –  Limited Atonement 15.01.2016, 19:10
  • 4
    Эта команда работает только с коротким списком файлов. Посмотрите то, что происходит, когда у Вас есть 850 000 файлов в каталоге!!! –  hamidfzm 20.05.2016, 13:07

Просто распечатайте текущую строку, из которой Вы суммируете общее количество:

dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
8
27.01.2020, 19:31

Добавление следующего к .bash_profile или .bashrc работает на меня.

dir ()
{
find . -iname "$@" -exec ls -lh {} \;
find . -iname "$@" -print0|xargs -r0 du -csh|tail -n 1;
}

Теперь, когда я делаю dir *.mp3, он делает рекурсивно и печатает общее количество в конце. Можно управлять, сколько глубины Вы хотите путем добавления maxdepth параметра к находке. Я знаю, что рабочая находка дважды не очень effiecnt идея. Но я не мог думать о лучшем пути. По крайней мере это сделало задание.

1
27.01.2020, 19:31

Используя du и awk оператор как упомянутый выше тот обеспечит то, что Вы ищете.

Пример: du /home/abc/Downloads/*.jpg | awk '{ print; total += $1 }; END { print "total size: ",total }'

Это перечислит все файлы в папке Downloads пользовательской abc, заканчивающейся в .jpg, и печатает сумму всех этих файлов в конце списка.

1
27.01.2020, 19:31

с перл:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Размер всех не скрытых PDF-файлов в текущем каталоге.

6
27.01.2020, 19:31

, чтобы получить оба, расчет вывода и размера DIR, без использования ни одного из Другие предлагаемые варианты, вы можете использовать Tee (1) и замену процесса ...

dir | tee >( awk '{ total += $4 }; END { print total }' )
0
27.01.2020, 19:31

Вы можете использовать du -h -c directory|tail -1

Это сгенерирует одну строку с использованием памяти.

21
27.01.2020, 19:31
du * | awk -v sum=0 '{print sum+=$1}' | tail -1
-2
27.01.2020, 19:31
du path_to_your_files/*.jpg | awk '{ total += $1 }; END { print total }'
0
27.01.2020, 19:31

Для подсчета файлов в каталоге по маске я склонен следовать этому подходу:

Для байтов

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total, " Bytes" }'

Для килобайт

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total/1024, " KB" }'

Для мегабайт

du -ac --bytes  | grep "zip$" | awk '{ print; total += $1 }; END { print "total lobsters: " total/1024/1024 " MB" }'

Вы поняли.

Разбивка проста:

  • du-использование диска
    • -a -все файлы
    • -c -всего байт
    • --bytes -вывод на печать в байтах [в более новых версиях bash, не уверен, что это применимо]
  • grep-g lobal r egular e xpression p rint [выводит выходные совпадающие шаблоны]
    • "zip$" -соответствующий шаблон. 'zip' - это строка, а '$' обозначает конец строки/строки/и т. д. -. В этом случае сопоставьте строки, которые END с 'zip'. И наоборот, размещение '^' в начале строки указывает, что шаблон будет в начале строки [т.е. :"^start" будет соответствовать строкам , начинающимся со словом 'start'] -Зная это, перенос строки в символы ^ и $ соответственно будет соответствовать строкам, которые начинаются/заканчиваются с использованием используемого шаблона. «^hello people$» будет соответствовать строкам, говорящим «привет, люди». "^hello (. *)people$" будет соответствовать строкам, говорящим "привет, французы" и "привет, программисты",, но не «привет, кодеры, у которых нет жизней»
  • awk-язык сценариев, запрограммированныйA ho ,W einberger иK ernighan . Не очень оригинальное название, но очень мощный язык, который отлично подходит для обработки текста и извлечения данных.
    • {печать; всего += $1 }
      • напечатать -напечатать текущую итерируемую строку
      • total += $1 -инициализировать переменную total, если это еще не сделано, и добавить первый блок, разделенный field separator, в данном случае space character. Это можно изменить с помощью флага -F.
      • ; -ограничитель строки/оператора. вы можете поместить несколько операторов awkв одну строку, используя это, аналогично завершению операторов командной строки linux. В противном случае вы могли бы иметь их в многострочной вещи, все еще окруженной {... }
      • END -это фактически означает, что awkвыполнит указанные действия перед выходом.
    • { print "всего лобстеров :" всего " байт" }
      • напечатать "всего лобстеров :" -первая часть выводимой строки
      • total -переменная, содержащая общую сумму повторенных строк
      • " Bytes" -заключительная часть печатной строки, добавленная в конец двух предыдущих операторов
      • Очевидно, что эти три утверждения инкапсулированы в { }, как и первая часть.

Итак, рассмотрим пример в случае, когда мы хотим подсчитать общее количество zip-файлов в каталоге:

du -ac --bytes

836544 ./wp-content/themes/astra.1.8.1.zip
934364 ./wp-content/themes/astra.2.0.1.zip
400033 ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218      ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275./wp-content/plugins/essential-addons-elementor-master.zip
170    ./wp-content/plugins/gravityforms/images/doctypes/icon_zip.gif
1969651./wp-content/plugins/acf.zip
4284   ./wp-content/plugins/types/application/controllers/api/handler/import_from_zip_file.php

Два компонента вывода: столбец 1 представлен числовыми значениями :836544, 934364... и т. д., а столбец 2 представляет собой путь к файлу.

Тем не менее,поскольку есть две строки, которые не соответствуют тому, что нам нужно-icon_zip.gifи import_from_zip_file.php-, мы хотим их исключить. Поскольку duне предоставляет способ рекурсивной фильтрации по расширению (, который я знаю о ), мы фильтруем, используяgrep

grep "zip$"

Это эффективно передает вывод из duв него и фильтрует строки, которые заканчиваются на zip , удаляя две записи, которые нам не нужны:

836544 ./wp-content/themes/astra.1.8.1.zip
934364 ./wp-content/themes/astra.2.0.1.zip
400033 ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218      ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275./wp-content/plugins/essential-addons-elementor-master.zip
1969651./wp-content/plugins/acf.zip

Затем awk анализирует каждую строку, при этом числа в col 1сохраняются в$1

Получаем вот это:

836544 ./wp-content/themes/astra.1.8.1.zip
934364 ./wp-content/themes/astra.2.0.1.zip
400033 ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.zip
117351218      ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.zip
1192275./wp-content/plugins/essential-addons-elementor-master.zip
1969651./wp-content/plugins/acf.zip
total lobsters:  128.339  MB
5
27.01.2020, 19:31

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

function dir() {
    ls -FAGl --color=always "${@}" | awk '{
                print;
                total += $4
            }; END {
                if (total < 1024)
                    print "\t\ttotal: ",total;
                else if (total < (1024 * 1024))
                    print "\t\ttotal: ",total/1024,"KB";
                else if (total < (1024 * 1024 * 1024))
                    print "\t\ttotal: ",total/(1024*1024),"MB";
                else if (total < (1024 * 1024 * 1024 * 1024))
                    print "\t\ttotal: ",total/(1024*1024*1024),"GB";
            }'
}

Вот как это работает:

-Fдобавляет индикатор (к одному из */=>@| )к записям

-Aне перечисляет подразумеваемые .и ..объекты

-Gопускает имена групп (в системах, которые включают их по умолчанию)

-lвыводит длинный список,это то, что нам нужно для получения размеров файлов

--color=alwaysдолжно быть само собой -понятное

"${@}"передает любые другие аргументы вls

Скрипт awk, который я собрал из нескольких источников, включая принятый здесь ответ, сначала печатает новую строку, а затем суммирует все числа в столбце 4. Затем это число проверяется, чтобы определить, меньше ли оно 1 КБ., 1 МБ, 1 ГБ и 1 ТБ соответственно. Затем он печатает итоговое значение в соответствующих единицах с отступом в 2 табуляции (16 пробелов ), что приблизительно соответствует размеру столбца в большинстве систем. Это можно настроить в соответствии с вашими потребностями.


Почему вы называете это dir? Это GNU coreutil!

Я назвал функцию dir, потому что я вырос на DOS, и когда я начал экспериментировать с ядром Linux (1.2! )друг предложил мне псевдоним dirкак ls -al, так как я так привык его печатать. Сейчас это просто мышечная память. В конце концов я узнал о /usr/bin/dir, но я предпочитаю иметь длинные списки каталогов, поэтому я никогда не удосужился изменить свой псевдоним, а теперь и функцию. Если вы используете программу dirи/или не хотите дублировать ее, не стесняйтесь называть функцию как хотите.

Почему бы вам не использовать du?

Да, когдавсеменя интересует, сколько места занимает каталог. Я хотел иметь эту функцию, когда я делаю списки каталогов (, что я делаю гораздо чаще ), поэтому эта функция родилась.

0
14.05.2021, 20:40

teeрешит проблему исчезновения вывода на экране, когда он передается другой команде, такой как awk.

Итак, команда:

ls -FaGl | printf "%'d\n" $(awk '{SUM+=$4}END{print SUM}')

который печатает только:

63,519,676,015

Заменяется командой:

ls -FaGl | tee /dev/stderr | printf "%'d\n" $(awk '{SUM+=$4}END{print SUM}')

и теперь отображается полный список файлов с общим количеством:

total 62031069
drwxrwxrwx 1 rick      20480 Oct  9 15:47./
drwxrwxrwx 1 rick      12288 Jul 20  2020../
drwxrwxrwx 1 rick          0 Oct 15  2017 Captures/
-rwxrwxrwx 1 rick        504 Jun 29  2020 desktop.ini*
drwxrwxrwx 1 rick       4096 Nov 18  2017 Mass Effect Andromeda/
-rwxrwxrwx 1 rick  210355992 Nov  8  2019 Screencapture 2019-11-08 at 13.07.14.mp4*
-rwxrwxrwx 1 rick  127445089 Nov  8  2019 Screencapture 2019-11-08 at 13.43.55.mp4*
-rwxrwxrwx 1 rick  997439911 Nov 11  2019 simplescreenrecorder-2019-11-11_21.42.51.mkv*
   ( Long listing snipped... )
-rwxrwxrwx 1 rick 1546689758 Sep  6 22:35 simplescreenrecorder-2021-09-06_21.18.29*
-rwxrwxrwx 1 rick  422607080 Sep 18 19:13 simplescreenrecorder-2021-09-18_18.57.00*
63,519,676,015

TL;DR

Вставьте | tee /dev/stderrв конвейер.

Итого в удобочитаемом формате

В моей собственной ~/.bashrcесть эта функция:

$ grep 'BytesToHuman(' -A20 ~/.bashrc

function BytesToHuman() {

    # https://unix.stackexchange.com/questions/44040/a-standard-tool-to-convert-a-byte-count-into-human-kib-mib-etc-like-du-ls1/259254#259254

    read StdIn
    if ! [[ $StdIn =~ ^-?[0-9]+$ ]] ; then
        echo "$StdIn"       # Simply pass back what was passed to us
        exit 1              # Floats or strings not allowed. Only integers.
    fi

    b=${StdIn:-0}; d=''; s=0; S=(Bytes {K,M,G,T,E,P,Y,Z}iB)
    while ((b > 1024)); do
        d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))"
        b=$((b / 1024))
        let s++
    done

    echo "$b$d ${S[$s]}"
    exit 0                  # Success!

} # BytesToHuman ()

Так что просто добавьте | BytesToHumanв конец конвейера. Также удалите printfвстроенную функцию, которая использовалась ранее :

.
ls -FaGl | tee /dev/stderr | awk '{SUM+=$4}END{print SUM}' | BytesToHuman

Теперь общее количество будет отображаться как:

59.15 GiB

Если вы предпочитаете видеть 63.51 GB, то функцию BytesToHuman()необходимо изменить с:

b=${StdIn:-0}; d=''; s=0; S=(Bytes {K,M,G,T,E,P,Y,Z}iB)
while ((b > 1024)); do
    d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))"
    b=$((b / 1024))

К:

b=${StdIn:-0}; d=''; s=0; S=(Bytes {K,M,G,T,E,P,Y,Z}B)
while ((b > 1000)); do
    d="$(printf ".%02d" $((b % 1000 * 100 / 1000)))"
    b=$((b / 1000))
0
10.10.2021, 13:03

Теги

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