Почему в сочетании с awk нет точных размеров?

Вы можете загрузиться с модулем radeon в черный список, а затем загрузить его в rc.local (modprobe radeon). Это сделало мою систему стабильной.

1
задан 7 April 2016 в 21:34

3 ответа

TL; DR: ls и awk не нужны для вашей цели. Используйте du -cb или du -bs в каталоге, который вы хотите проанализировать.

Ваша цель состоит в

Найти все файлы, чтобы найти их размер (в байтах), произвести общую сумму для всех из них

Все эти действия могут выполняться с помощью [ f8].

$ du -bs $HOME 2>/dev/null                                                                 
76709521942 /home/xieerqi

Стоит заметить, что du имеет два «режима» - он может либо показать, сколько файлов имеет размер, либо сколько фактического дискового пространства он занимает (реальная, физическая недвижимость ). Поскольку вас интересует общий размер всех файлов, вам нужен размер файла. Флаг -b дает именно то, что [-b является псевдонимом для --apparent-size --block-size=1).

Возможно, еще более кратким и подходящим решением было бы использовать du -bc непосредственно в каталоге, который вы хотите. Например, мой домашний каталог имеет размер около 76 ГБ

$ du -bc $HOME 2> /dev/null  | tail -1                    
76694582570 total

По какой-то причине вы беспокоитесь о различии в размере папки и размере файла. Вы сказали в комментариях:

I предпочитает ls, так как размеры директорий меняются, а размеры файлов постоянны.

du является рекурсивным и суммирует размеры файлов. Кроме того, каталог имеет статический размер 4096 байт (4k), но с du он будет включен в результат du -bs directory_name. Рассмотрим это:

$ du -b suse/openSUSE-Leap-42.1-DVD-x86_64.iso                                             
4648337408  suse/openSUSE-Leap-42.1-DVD-x86_64.iso

$ du -b suse/                                                                              
4648341504  suse/

$ bc <<< "4648337408+4096" 
4648341504

$ mkdir suse/another_dir  

$ du -b suse/another_dir                                                                   
4096    suse/another_dir

$ du -bs suse/                                                                             
4648345600  suse/
5
ответ дан 23 May 2018 в 12:19
  • 1
    @kos -s производит общее количество для каждого аргумента, поэтому, если аргументы были каталогами, он создавал бы сводку для всех из них и выводил бы для size dir_name, поэтому последняя строка была бы тем самым последним аргументом. -c фактически производит сумму размеров всех приведенных аргументов и дает последнюю строку как общую сумму :) – Sergiy Kolodyazhnyy 7 April 2016 в 18:10
  • 2
    Я имел в виду буквальный du -s ., а не find . -type f -exec du -s {} \+ 2> /dev/null | awk 'END{print $0}' (и, кстати, поскольку они хотят байтов, я исправлю это до du -bs .). – kos 7 April 2016 в 18:26
  • 3
    @kos Я добавил это к моему ответу :) – Sergiy Kolodyazhnyy 7 April 2016 в 18:44
  • 4
    Я просто перечитывал и тестировал снова, извините, я не знал, что -b подразумевается --apparent-size. Удалено это замечание (и неточное первое замечание). – kos 7 April 2016 в 18:47
  • 5
    Я всегда использую du -cks, который полезен, легко запоминается и смешон. – MarkHu 7 April 2016 в 23:16

Под капотом awk выполняет все вычисления с использованием чисел с плавающей запятой с двойной точностью. По умолчанию он печатает их с помощью спецификатора формата printf(3) %.6g, а это означает, что если число больше шестизначных чисел, оно переключится на E-нотацию, что вы видели. Вы можете обойти это, установив переменную OFMT:

ls -lR |
    awk 'BEGIN { OFMT = "%d" }  
         /^-/  { total += $5 } 
         END   { print "Total:", total }'

Но есть верхний предел, за которым он не может дать вам точное количество байтов; он начнет округлять низкие биты суммы. 500 гигабайт = 500 * 1024 * 1024 * 1024 = 536870912000 & approx; 239. С обычной плавающей точкой IEEE это безопасно ниже этого предела (что примерно равно 252). Тем не менее, он достаточно велик, что я лично почувствовал бы себя лучше, используя язык программирования, который имел бы правильные «бонусы» (неограниченные целые числа). Например, Python:

#! /usr/bin/python
import os
import sys

space = 0L  # L means "long" - not necessary in Python 3
for subdir, dirs, files in os.walk(sys.argv[1]):
    for f in files:
        space += os.lstat(os.path.join(subdir, f)).st_size

sys.stdout.write("Total: {:d}\n".format(space))

Это также полностью невосприимчиво к проблемам с файлами с необычными символами в их именах. И он подсчитывает пространство, потребляемое скрытыми файлами.

Это вычисляет не может , что совпадает с тем, что печатает ls -l. Если вы хотите, чтобы количество фактически занятых байтов на диске (что du печатает), замените .st_size на .st_blocks * 512. (Да, множитель всегда 512, даже если st_blksize - это другое число.)

4
ответ дан 23 May 2018 в 12:19
  • 1
    Вы перепутали заказ. Прочитайте документацию . Заказ должен быть dirpath, dirnames, filenames – Sergiy Kolodyazhnyy 7 April 2016 в 21:27
  • 2
    @Serg Я просто исправил это :) – zwol 7 April 2016 в 21:28
  • 3
    У меня была небольшая проблема с вашим кодом, поэтому пришлось задать вопрос. Посмотреть мой пост stackoverflow.com/q/36484470/3701431 – Sergiy Kolodyazhnyy 7 April 2016 в 21:43
  • 4
    +1, но на стороне обратите внимание, что верхний предел перед переключением на научную нотацию не является точным, ни в GAWK, ни в MAWK (вариант AWK по умолчанию на Ubuntu, где верхний предел выше, 2 ^ 32, т. Е. Обычный максимум размер int, максимальное число представляемое - 2147483647). Кажется, что у GAWK есть еще больший верхний предел, хотя я не тестировал его, и я не просмотрел документацию / исходный код (пока). – kos 7 April 2016 в 21:58
  • 5
    @Serg Gah, я должен был подумать об этом - ответ теперь исправлен. Исправлено right для проблемы symlink, которую вы обнаружили, это использовать os.lstat вместо os.stat, потому что в этом контексте вы do хотите подсчитать размер символических ссылок и вам не нужно хотеть подсчитать размер того, на что они указывают (если указатель находится внутри дерева, он должен учитываться только один раз, если он вне его, его не следует считать вообще) , – zwol 8 April 2016 в 23:34

То, что вы видите здесь, - это способ отображения больших чисел. Например:

1.23e+3 = 1.23*10^3 = 1230

Насколько я знаю, вы не можете отключить это, но, как вы писали в своем вопросе, du ведет себя по-другому, поэтому я бы рекомендовал использовать это. В противном случае вам придется преобразовать числа.

3
ответ дан 23 May 2018 в 12:19

Другие вопросы по тегам:

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