@ haunted85 stat- самый простой способ, при условии, что вы используете Linux или Cygwin ( statне является стандартным). wc -cкак предложено Евгением, является портативным.
Жиль
2
stat: illegal option -- c
Юлиан
stat --printf="%s" file.txtничего не выводит на Debian, Джесси ...
woohoo
5
На MacOS это работает:stat -f%z myfile.tar
ccpizza
2
@woohoo Ваша подсказка перезаписывает вывод. man statговорит, что --printf пропускает завершающий перевод строки. Используйте --formatили, -cчтобы увидеть результат. Получить больше понимания путем сравнения stat --printf="%s" file.any | xxd -сstat -c "%s" file.any | xxd -
внуком
92
file_size_kb=`du -k "$filename" | cut -f1`
Проблема с использованием statзаключается в том, что это расширение GNU (Linux). du -kи cut -f1определяются POSIX и поэтому переносимы на любую систему Unix.
Солярис, например, поставляется с Bash, но не с stat. Так что это не совсем гипотетически.
lsимеет аналогичную проблему в том, что точный формат вывода не указан, поэтому анализ его вывода не может быть выполнен переносимым. du -hтакже расширение GNU.
Придерживайтесь переносных конструкций, где это возможно, и в будущем вы сделаете чью-то жизнь проще. Может быть, ваш собственный.
duне дает размер файла, он показывает, сколько места занимает файл, что немного отличается (обычно размер, о котором сообщается, du- это размер файла, округленный до ближайшего числа блоков, где блок обычно составляет 512B или 1kB или 4kB).
Жиль
7
@ Жиль, разреженные файлы (то есть файлы с дырами в них) сообщают о длине меньше.
vonbrand
5
Это, с --bytesили -bвместо -k, должен быть принятым ответом.
Амеди Ван Гасс
1
Параметр -h("человек")du даст наиболее подходящий ответ для общих случаев: file_size=`du -h "$filename" | cut -f1он будет отображать K (килобайт), M (мегабайт) или G (гигабайт) в зависимости от ситуации.
fralau
1
@fralau: OP хочет «назначить это переменной bash, чтобы они могли использовать ее позже», так что гораздо более вероятно, что они хотят получить фактическое числовое значение, а не понятное для человека приближение. Кроме того, -hэто расширение GNU; это не стандартно
Nemo
74
Вы также можете использовать команду «подсчет слов» ( wc):
wc -c "$filename"| awk '{print $1}'
Проблема в wcтом, что он добавит имя файла и сделает отступ. Например:
$ wc -c somefile.txt1160 somefile.txt
Если вы хотите избежать создания цепочки полностью интерпретируемого языка или потокового редактора просто для того, чтобы получить счетчик размера файла, просто перенаправьте ввод из файла, чтобы wcникогда не видеть имя файла:
wc -c <"$filename"
Эта последняя форма может использоваться с подстановкой команд, чтобы легко получить значение, которое вы искали, как переменную оболочки, как упомянуто Жилем ниже.
wc -c <"$FILENAME"таким образом, дает размер без какой-либо другой обработки size=$(wc -c <"$FILENAME").
Жиль
6
Еще один момент: я только что проверил это и, wc -c < fileкажется, очень быстро, по крайней мере, на OS X. Я предполагаю, что у wc есть мозги, чтобы попытаться определить файл, если указан только -c.
Эдвард Фальк
4
@EdwardFalk: GNU wc -cиспользует fstat, но затем ищет второй-последний блок файла и читает последние st_blksizeбайты. Очевидно, это связано с тем, что файлы в Linux /procи, /sysнапример, имеют размеры статистики, которые являются только приблизительными , и wcхотят сообщить фактический размер, а не размер, указанный в статистике. Я предполагаю, что было бы странно wc -cсообщать о размере, отличном wcот указанного, но считывать данные из файла не рекомендуется, если это обычный файл на диске и он не находится в памяти. Или еще хуже, почти линия хранения ленты ...
Питер Кордес
1
Кажется, что printfвсе еще видит отступ, например printf "Size: $size"-> size: <4 spaces> 54339. С другой стороны echoигнорирует пробелы. Любой способ сделать это последовательным?
Евгений Кулабухов
2
@keithpjolley: по телефону fstat. Попробуйте запустить, strace wc -c </etc/passwdи вы можете увидеть, что он делает.
Немо
48
У BSD (Mac OS X) statесть другой флаг аргумента формата и другие спецификаторы поля. От man stat(1):
-f format: Отображение информации в указанном формате. Смотрите раздел FORMATS для описания допустимых форматов.
Зависит от того, что вы подразумеваете под размером .
size=$(wc -c <"$file")
даст вам количество байтов, которые можно прочитать из файла. IOW, это размер содержимого файла. Тем не менее, он будет читать содержимое файла (за исключением случаев, когда файл является обычным файлом или символической ссылкой на обычный файл в большинстве wcреализаций в качестве оптимизации). Это может иметь побочные эффекты. Например, для именованного канала, то, что было прочитано, больше не может быть прочитано снова, а для таких вещей, как /dev/zeroили /dev/randomкоторые имеют бесконечный размер, это займет некоторое время. Это также означает, что вам нужно readразрешение на файл, и последняя отметка времени доступа к файлу может быть обновлена.
Это стандартно и переносимо, однако обратите внимание, что некоторые wcреализации могут включать начальные пробелы в этом выводе. Один из способов избавиться от них - использовать:
size=$(($(wc -c <"$file")))
или чтобы избежать ошибки о пустом арифметическом выражении в dashили yashкогда wcничего не выводится (например, когда файл не может быть открыт):
size=$(($(wc -c <"$file")+0))
ksh93имеет wcвстроенную функцию (при условии, что вы ее включите, вы также можете вызывать ее как command /opt/ast/bin/wc), что делает ее наиболее эффективной для обычных файлов в этой оболочке.
Различные системы имеют команду с именем , statчто это интерфейс к stat()или lstat()системным вызовам.
Те сообщают информацию, найденную в inode. Одной из этих сведений является st_sizeатрибут. Для обычных файлов это размер контента (сколько данных можно прочитать из него при отсутствии ошибок (это то, что большинство wc -cреализаций используют при оптимизации)). Для символических ссылок это размер в байтах целевого пути. Для именованных каналов, в зависимости от системы, это либо 0, либо количество байтов, находящихся в данный момент в буфере канала. То же самое для блочных устройств, где в зависимости от системы вы получаете 0 или размер в байтах базового хранилища.
Вам не нужно разрешение на чтение файла, чтобы получить эту информацию, только разрешение на поиск в каталоге, с которым он связан.
stat -f %z --"$file"# st_size of file
stat -Lf%z --"$file"# after symlink resolution
Или вы можете использовать stat()/ lstat()функцию некоторых скриптовых языков, таких как perl:
perl -le 'print((lstat shift)[7])'--"$file"
В AIX также есть istatкоманда, которая будет выгружать всю информацию stat()(нет lstat(), поэтому не будет работать с символическими ссылками) и которую вы могли бы обработать, например:
Задолго до того, как GNU представила свою statкоманду, того же можно добиться с помощью findкоманды GNU с ее -printfпредикатом (уже в 1991 году):
find --"$file"-prune -printf '%s\n'# st_size of file
find -L --"$file"-prune -printf '%s\n'# after symlink resolution
Одна проблема , хотя в том , что не работает , если $fileначинается с -или в findпредикат (например !, (...).
Стандартная команда для получения информации stat()/ .lstat()ls
POSIXly, вы можете сделать:
LC_ALL=C ls -dn --"$file"| awk '{print $5; exit}'
и добавить -Lто же самое после разрешения символической ссылки. Это не работает для файлов устройств, хотя 5- е поле - это номер устройства, а не его размер.
Для блочных устройств системы, где stat()возвращается 0 для st_size, обычно имеют другие API-интерфейсы для сообщения о размере блочного устройства. Например, Linux имеет BLKGETSIZE64ioctl(), и большинство дистрибутивов Linux теперь поставляются с blockdevкомандой, которая может использовать ее:
blockdev --getsize64 --"$device_file"
Однако для этого вам нужно разрешение на чтение файла устройства. Обычно можно получить размер другими способами. Например (все еще в Linux):
lsblk -bdno size --"$device_file"
Должно работать за исключением пустых устройств.
Подход, который работает для всех доступных для поиска файлов (включая обычные файлы, большинство блочных устройств и некоторые символьные устройства), заключается в открытии файла и поиске до конца:
С zsh(после загрузки zsh/systemмодуля):
{sysseek -w end 0&& size=$((systell(0)))}< $file
С ksh93:
<"$file"<#((size=EOF))
или же
{ size=$(<#((EOF)));}<"$file"
с perl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN'<"$file"
Для именованных каналов мы видели, что некоторые системы (по крайней мере, AIX, Solaris, HP / UX) делают объем данных в буфере канала доступным в stat()'s st_size. Некоторые (например, Linux или FreeBSD) этого не делают.
По крайней мере, в Linux вы можете использовать FIONREADioctl()после открытия канала (в режиме чтения + записи, чтобы избежать его зависания):
Однако обратите внимание, что хотя он не читает содержимое канала, простое открытие именованного канала может иметь побочные эффекты. fuserСначала мы используем, чтобы проверить, что какой-то процесс уже имеет открытую трубу, чтобы облегчить это, но это не является надежной задачей, так как fuserне может проверить все процессы.
Пока что мы рассматривали только размер первичных данных, связанных с файлами. Это не учитывает размер метаданных и всю вспомогательную инфраструктуру, необходимую для хранения этого файла.
Другой атрибут inode, возвращаемый stat()is st_blocks. Это количество 512-байтовых блоков, которое используется для хранения данных файла (а иногда и некоторых его метаданных, таких как расширенные атрибуты в файловых системах ext4 в Linux). Это не включает в себя сам индекс или записи в каталогах, с которыми связан файл.
Размер и использование диска не обязательно тесно связаны как сжатие, разреженность (иногда некоторые метаданные), дополнительная инфраструктура, например косвенные блоки в некоторых файловых системах, влияют на последнюю.
Это обычно то, что duиспользуется, чтобы сообщить об использовании диска. Большинство команд, перечисленных выше, смогут получить эту информацию.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file" (не для каталогов, где это будет включать в себя использование диска файлов внутри).
явно самый полный и информационный ответ. благодарю вас. я могу использовать это для создания межплатформенных скриптов bash, используя информацию статистики BSD и GNU
не будет ли эта работа тожеls -go file | awk '{print $3}'
Стивен Пенни
@StevenPenny - это -goбудут SysV, они не будут работать на BSD (опционально (XSI) в POSIX). Вам также понадобится ls -god file | awk '{print $3; exit}'( -dдля работы с каталогами, exitдля символических ссылок с символами новой строки в цели). Проблемы с файлами устройств также остаются.
Стефан Шазелас
1
@ αғsнιη Unix API не делает различий между текстовыми и двоичными файлами. Это все последовательности байтов. Некоторым приложениям может потребоваться интерпретировать эти байты как текст, но, очевидно, нет, wc -cкоторый сообщает количество байтов.
Стефан Шазелас
22
Этот скрипт объединяет множество способов расчета размера файла:
(
du --apparent-size --block-size=1"$file"2>/dev/null ||
gdu --apparent-size --block-size=1"$file"2>/dev/null ||
find "$file"-printf "%s"2>/dev/null ||
gfind "$file"-printf "%s"2>/dev/null ||
stat --printf="%s""$file"2>/dev/null ||
stat -f%z "$file"2>/dev/null ||
wc -c <"$file"2>/dev/null)| awk '{print $1}'
Скрипт работает во многих системах Unix, включая Linux, BSD, OSX, Solaris, SunOS и т. Д.
Размер файла показывает количество байтов. Это очевидный размер, который представляет собой байты, которые файл использует на типичном диске, без специального сжатия, особых разреженных областей, нераспределенных блоков и т. Д.
Я думаю, что ls -lи statкоманда и команда дают достоверную информацию о размере. Я не нашел никаких ссылок на обратное. ls -sдаст размер в количестве блоков.
dabest1
2
@ dabest1 это ненадежно в том смысле, что в другом Unix их вывод может быть другим (а в некоторых Unix это так).
Евгений Бужак
Да, IIRC, Solaris не отображал имя группы по умолчанию, что привело к уменьшению количества столбцов в выводе.
Эдвард Фальк
Поскольку размер является чисто числовым, окружен пробелами, а год даты является чисто числовым, в определенном формате можно было бы использовать регулярное выражение, чтобы рассматривать пользователя + владельца как одно поле, независимо от того, присутствовала ли группа. (упражнение для читателя!)
MikeW
5
du filename скажет вам использование диска в байтах.
Я предпочитаю du -h filename, который дает вам размер в удобочитаемом формате.
Этот аромат duвыводит размер в блоках по 1024 байта, а не в простое число байтов.
Питер Лайонс
Обратите внимание, что стандарт duдает выход в количестве 512 байт. duВместо этого GNU использует кибибайты, если POSIXLY_CORRECTв своей среде они не вызваны .
Стефан Шазелас
1
Для файлов типа каталог , это дает использование диска каталогом, но также и всеми другими файлами внутри (рекурсивно).
Стефан Шазелас
3
Создайте в своих сценариях оболочки небольшие служебные функции, которым вы можете делегировать.
пример
#! /bin/sh -# vim: set ft=sh# size utility that works on GNU and BSD systems
size(){case $(uname)in(Darwin|*BSD*)
stat -Lf%z --"$1";;(*) stat -c %s --"$1"esac}for f do
printf '%s\n'"$f : $(gzip < "$f" | wc -c) bytes (versus $(size "$f") bytes)"done
@ StéphaneChazelas не уверен, если я думаю, что это было улучшение. те заявления случая могут легко оттолкнуть новичков; Я, конечно, никогда не помню, как правильно их понять :-) Являются ли операторы по своей сути более переносимыми с тех пор, как вы это сделали? я вижу момент, когда есть более двух случаев, но в остальном ... +
oligofren
1
Я предполагаю, что это также вопрос вкуса, но здесь это типичный случай, когда вы хотите использовать caseутверждение. caseявляется конструкцией Bourne / POSIX для сопоставления с образцом [[...]]только ksh / bash / zsh (с вариациями).
Стефан
2
Я нашел вкладыш AWK 1, и в нем была ошибка, но я исправил ее. Я также добавил в PetaBytes после TeraBytes.
Учитывая, что статистика доступна не для каждой отдельной системы, вы почти всегда можете использовать решение AWK. Пример; у Raspberry Pi нет статов, но есть awk .
Совершенно НЕ то, что спросил ОП, но хороший маленький кусочек работы.
цыганский заклинатель
0
Еще один совместимый с POSIX способ заключается в использовании awkс его length()функцией, которая возвращает длину, символов в каждой строке входного файла, исключая символы новой строки. Итак, делая
awk '{ sum+=length } END { print sum+NR }' file
мы обеспечиваем NRдобавление к нему sum, что приводит к общему количеству символов и общему количеству новых строк, встречающихся в файле. length()Функция awkпринимает которая аргумент с помощью по умолчанию , length($0)который является для текущей всей линии.
Не, если последняя строка не заканчивается на новой строке: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'должно быть напечатано 3, но напечатано 4.
Исаак
-1
Мне нравится вариант wc сам. В паре с «bc» вы можете получить десятичные знаки в любом количестве мест, где пожелаете.
Я пытался улучшить сценарий, который у меня был, чтобы исключить столбец «размер файла» команды «ls -alh». Я не хотел просто целочисленные размеры файлов, и два десятичных знака, казалось, подходили, поэтому после прочтения этого обсуждения я пришел к приведенному ниже коду.
Я предлагаю разбить строку на точку с запятой, если вы включите это в скрипт.
Мой сценарий называется gpfl , для «получить длину файла изображения». Я использую его после выполнения mogrify для файла в imagemagick, перед открытием или повторной загрузкой изображения в программе просмотра JPEG с графическим интерфейсом.
Я не знаю, как это оценивается как «ответ», поскольку он многое заимствует из того, что уже было предложено и обсуждено. Так что я оставлю это там.
Я бы предпочел использовать «stat» или «ls». Обычно я не люблю использовать «wc» для получения размеров файлов, потому что он физически читает весь файл. Если у вас много файлов или особенно больших файлов, это может занять много времени. Но ваше решение креативно ... + 1.
Кевин Феган,
2
Я согласен с понятием использования «stat» над «wc» для размера файла, однако, если вы используете «wc -c», никакие данные не будут прочитаны; вместо этого будет использоваться lseek для определения количества байтов в файле. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42
1
@ bbaja42: обратите внимание, что GNU Coreutils wcчитает последний блок файла, на случай, если stat.st_sizeэто только приблизительное значение (как для Linux /procи /sysфайлов). Я думаю, что они решили не делать основной комментарий более сложным, когда добавили эту логику на пару строк ниже: lingrok.org/xref/coreutils/src/wc.c#246
Затем добавьте один или несколько существующих ответов, в которых упоминается статистика; нет необходимости повторять это снова ...
Джефф Шаллер
1
@JeffSchaller Я только что проголосовал за ответ Стефана на твои инструкции. Я думаю, что это слишком сложно для моих целей. Вот почему я написал этот простой ответ для единомышленников.
WinEunuuchs2Unix
1
Спасибо; просто шестой случай ответа «stat» не упрощает эти вопросы и ответы, а скорее заставит нового читателя спросить себя: «Чем этот ответ отличается от других?» и привести к большей путанице, а не меньше.
Джефф Шаллер
@JeffSchaller Я думаю. Но я мог бы жаловаться многие duи wcответы , которые должны иметь отказ от ответственности НИКОГДА НЕ ЭТО в реальной жизни. Сегодня вечером я использовал свой ответ в реальном приложении и подумал, что им стоит поделиться. Я думаю, что у всех нас есть наше мнение пожимает плечами .
pv
иcat
для команды копирования, которая показывает прогресс и ETA :)Ответы:
Ваш лучший выбор, если в системе GNU:
От человека стат :
В скрипте bash:
ПРИМЕЧАНИЕ: см . Ответ @ chbrown о том, как использовать stat в терминале в Mac OS X.
источник
stat
- самый простой способ, при условии, что вы используете Linux или Cygwin (stat
не является стандартным).wc -c
как предложено Евгением, является портативным.stat: illegal option -- c
stat --printf="%s" file.txt
ничего не выводит на Debian, Джесси ...stat -f%z myfile.tar
man stat
говорит, что --printf пропускает завершающий перевод строки. Используйте--format
или,-c
чтобы увидеть результат. Получить больше понимания путем сравненияstat --printf="%s" file.any | xxd -
сstat -c "%s" file.any | xxd -
Проблема с использованием
stat
заключается в том, что это расширение GNU (Linux).du -k
иcut -f1
определяются POSIX и поэтому переносимы на любую систему Unix.Солярис, например, поставляется с Bash, но не с
stat
. Так что это не совсем гипотетически.ls
имеет аналогичную проблему в том, что точный формат вывода не указан, поэтому анализ его вывода не может быть выполнен переносимым.du -h
также расширение GNU.Придерживайтесь переносных конструкций, где это возможно, и в будущем вы сделаете чью-то жизнь проще. Может быть, ваш собственный.
источник
du
не дает размер файла, он показывает, сколько места занимает файл, что немного отличается (обычно размер, о котором сообщается,du
- это размер файла, округленный до ближайшего числа блоков, где блок обычно составляет 512B или 1kB или 4kB).--bytes
или-b
вместо-k
, должен быть принятым ответом.-h
("человек")du
даст наиболее подходящий ответ для общих случаев:file_size=`du -h "$filename" | cut -f1
он будет отображать K (килобайт), M (мегабайт) или G (гигабайт) в зависимости от ситуации.-h
это расширение GNU; это не стандартноВы также можете использовать команду «подсчет слов» (
wc
):Проблема в
wc
том, что он добавит имя файла и сделает отступ. Например:Если вы хотите избежать создания цепочки полностью интерпретируемого языка или потокового редактора просто для того, чтобы получить счетчик размера файла, просто перенаправьте ввод из файла, чтобы
wc
никогда не видеть имя файла:Эта последняя форма может использоваться с подстановкой команд, чтобы легко получить значение, которое вы искали, как переменную оболочки, как упомянуто Жилем ниже.
источник
wc -c <"$FILENAME"
таким образом, дает размер без какой-либо другой обработкиsize=$(wc -c <"$FILENAME")
.wc -c < file
кажется, очень быстро, по крайней мере, на OS X. Я предполагаю, что у wc есть мозги, чтобы попытаться определить файл, если указан только -c.wc -c
используетfstat
, но затем ищет второй-последний блок файла и читает последниеst_blksize
байты. Очевидно, это связано с тем, что файлы в Linux/proc
и,/sys
например, имеют размеры статистики, которые являются только приблизительными , иwc
хотят сообщить фактический размер, а не размер, указанный в статистике. Я предполагаю, что было бы странноwc -c
сообщать о размере, отличномwc
от указанного, но считывать данные из файла не рекомендуется, если это обычный файл на диске и он не находится в памяти. Или еще хуже, почти линия хранения ленты ...printf
все еще видит отступ, напримерprintf "Size: $size"
->size: <4 spaces> 54339
. С другой стороныecho
игнорирует пробелы. Любой способ сделать это последовательным?fstat
. Попробуйте запустить,strace wc -c </etc/passwd
и вы можете увидеть, что он делает.У BSD (Mac OS X)
stat
есть другой флаг аргумента формата и другие спецификаторы поля. Отman stat(1)
:-f format
: Отображение информации в указанном формате. Смотрите раздел FORMATS для описания допустимых форматов.z
: Размер файла в байтах.Итак, все вместе сейчас:
источник
Зависит от того, что вы подразумеваете под размером .
даст вам количество байтов, которые можно прочитать из файла. IOW, это размер содержимого файла. Тем не менее, он будет читать содержимое файла (за исключением случаев, когда файл является обычным файлом или символической ссылкой на обычный файл в большинстве
wc
реализаций в качестве оптимизации). Это может иметь побочные эффекты. Например, для именованного канала, то, что было прочитано, больше не может быть прочитано снова, а для таких вещей, как/dev/zero
или/dev/random
которые имеют бесконечный размер, это займет некоторое время. Это также означает, что вам нужноread
разрешение на файл, и последняя отметка времени доступа к файлу может быть обновлена.Это стандартно и переносимо, однако обратите внимание, что некоторые
wc
реализации могут включать начальные пробелы в этом выводе. Один из способов избавиться от них - использовать:или чтобы избежать ошибки о пустом арифметическом выражении в
dash
илиyash
когдаwc
ничего не выводится (например, когда файл не может быть открыт):ksh93
имеетwc
встроенную функцию (при условии, что вы ее включите, вы также можете вызывать ее какcommand /opt/ast/bin/wc
), что делает ее наиболее эффективной для обычных файлов в этой оболочке.Различные системы имеют команду с именем ,
stat
что это интерфейс кstat()
илиlstat()
системным вызовам.Те сообщают информацию, найденную в inode. Одной из этих сведений является
st_size
атрибут. Для обычных файлов это размер контента (сколько данных можно прочитать из него при отсутствии ошибок (это то, что большинствоwc -c
реализаций используют при оптимизации)). Для символических ссылок это размер в байтах целевого пути. Для именованных каналов, в зависимости от системы, это либо 0, либо количество байтов, находящихся в данный момент в буфере канала. То же самое для блочных устройств, где в зависимости от системы вы получаете 0 или размер в байтах базового хранилища.Вам не нужно разрешение на чтение файла, чтобы получить эту информацию, только разрешение на поиск в каталоге, с которым он связан.
По хронологическому порядку есть:
IRIX
stat
(90-е):возвращает
st_size
атрибут$file
(lstat()
) или:То же самое, за исключением случаев, когда
$file
это символическая ссылка, и в этом случае этоst_size
файл после разрешения символической ссылки.zsh
stat
Встроенный (теперь также известный какzstat
) вzsh/stat
модуле (загружен сzmodload zsh/stat
) (1997):или хранить в переменной:
очевидно, это самый эффективный в этой оболочке.
GNU
stat
(2001); также в BusyBoxstat
с 2005 года (скопировано из GNUstat
):(обратите внимание, что значение
-L
обратное по сравнению с IRIX илиzsh
stat
.BSDs
stat
(2002):Или вы можете использовать
stat()
/lstat()
функцию некоторых скриптовых языков, таких какperl
:В AIX также есть
istat
команда, которая будет выгружать всю информациюstat()
(нетlstat()
, поэтому не будет работать с символическими ссылками) и которую вы могли бы обработать, например:(спасибо @JeffSchaller за помощь в выяснении деталей ).
В
tcsh
:(размер после разрешения символической ссылки)
Задолго до того, как GNU представила свою
stat
команду, того же можно добиться с помощьюfind
команды GNU с ее-printf
предикатом (уже в 1991 году):Одна проблема , хотя в том , что не работает , если
$file
начинается с-
или вfind
предикат (например!
,(
...).Стандартная команда для получения информации
stat()
/ .lstat()
ls
POSIXly, вы можете сделать:
и добавить
-L
то же самое после разрешения символической ссылки. Это не работает для файлов устройств, хотя 5- е поле - это номер устройства, а не его размер.Для блочных устройств системы, где
stat()
возвращается 0 дляst_size
, обычно имеют другие API-интерфейсы для сообщения о размере блочного устройства. Например, Linux имеетBLKGETSIZE64
ioctl()
, и большинство дистрибутивов Linux теперь поставляются сblockdev
командой, которая может использовать ее:Однако для этого вам нужно разрешение на чтение файла устройства. Обычно можно получить размер другими способами. Например (все еще в Linux):
Должно работать за исключением пустых устройств.
Подход, который работает для всех доступных для поиска файлов (включая обычные файлы, большинство блочных устройств и некоторые символьные устройства), заключается в открытии файла и поиске до конца:
С
zsh
(после загрузкиzsh/system
модуля):С
ksh93
:или же
с
perl
:Для именованных каналов мы видели, что некоторые системы (по крайней мере, AIX, Solaris, HP / UX) делают объем данных в буфере канала доступным в
stat()
'sst_size
. Некоторые (например, Linux или FreeBSD) этого не делают.По крайней мере, в Linux вы можете использовать
FIONREAD
ioctl()
после открытия канала (в режиме чтения + записи, чтобы избежать его зависания):Однако обратите внимание, что хотя он не читает содержимое канала, простое открытие именованного канала может иметь побочные эффекты.
fuser
Сначала мы используем, чтобы проверить, что какой-то процесс уже имеет открытую трубу, чтобы облегчить это, но это не является надежной задачей, так какfuser
не может проверить все процессы.Пока что мы рассматривали только размер первичных данных, связанных с файлами. Это не учитывает размер метаданных и всю вспомогательную инфраструктуру, необходимую для хранения этого файла.
Другой атрибут inode, возвращаемый
stat()
isst_blocks
. Это количество 512-байтовых блоков, которое используется для хранения данных файла (а иногда и некоторых его метаданных, таких как расширенные атрибуты в файловых системах ext4 в Linux). Это не включает в себя сам индекс или записи в каталогах, с которыми связан файл.Размер и использование диска не обязательно тесно связаны как сжатие, разреженность (иногда некоторые метаданные), дополнительная инфраструктура, например косвенные блоки в некоторых файловых системах, влияют на последнюю.
Это обычно то, что
du
используется, чтобы сообщить об использовании диска. Большинство команд, перечисленных выше, смогут получить эту информацию.POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(не для каталогов, где это будет включать в себя использование диска файлов внутри).find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
источник
wc -c
используетfstat
, но затем читает последниеst_blksize
байты. Очевидно, это потому, что файлы в Linux/proc
и,/sys
например, имеют размеры статистики, которые являются только приблизительными . Это хорошо для корректности, но плохо, если конец файла находится на диске, а не в памяти (особенно, если он используется во многих файлах в цикле). И очень плохо, если файл переносится в ленточное хранилище с близким сроком хранения или, например, в файловую систему с прозрачной декомпрессией FUSE.ls -go file | awk '{print $3}'
-go
будут SysV, они не будут работать на BSD (опционально (XSI) в POSIX). Вам также понадобитсяls -god file | awk '{print $3; exit}'
(-d
для работы с каталогами,exit
для символических ссылок с символами новой строки в цели). Проблемы с файлами устройств также остаются.wc -c
который сообщает количество байтов.Этот скрипт объединяет множество способов расчета размера файла:
Скрипт работает во многих системах Unix, включая Linux, BSD, OSX, Solaris, SunOS и т. Д.
Размер файла показывает количество байтов. Это очевидный размер, который представляет собой байты, которые файл использует на типичном диске, без специального сжатия, особых разреженных областей, нераспределенных блоков и т. Д.
Этот скрипт имеет производственную версию с дополнительной справкой и дополнительными опциями здесь: https://github.com/SixArm/file-size
источник
stat, кажется, делает это с наименьшим количеством системных вызовов:
источник
ls -l filename
предоставит вам много информации о файле, включая его размер, права доступа и владельца.Размер файла в пятом столбце и отображается в байтах. В приведенном ниже примере размер файла составляет чуть менее 2 КБ:
Изменить: Это, очевидно, не так надежно, как
stat
команда.источник
ls -l
иstat
команда и команда дают достоверную информацию о размере. Я не нашел никаких ссылок на обратное.ls -s
даст размер в количестве блоков.du filename
скажет вам использование диска в байтах.Я предпочитаю
du -h filename
, который дает вам размер в удобочитаемом формате.источник
stat -c "%s"
;)du
выводит размер в блоках по 1024 байта, а не в простое число байтов.du
дает выход в количестве 512 байт.du
Вместо этого GNU использует кибибайты, еслиPOSIXLY_CORRECT
в своей среде они не вызваны .Создайте в своих сценариях оболочки небольшие служебные функции, которым вы можете делегировать.
пример
Основано на информации из ответа Стефана Шазеля.
источник
gzip -v < file > /dev/null
чтобы проверить сжимаемость файла.case
утверждение.case
является конструкцией Bourne / POSIX для сопоставления с образцом[[...]]
только ksh / bash / zsh (с вариациями).Я нашел вкладыш AWK 1, и в нем была ошибка, но я исправил ее. Я также добавил в PetaBytes после TeraBytes.
Учитывая, что статистика доступна не для каждой отдельной системы, вы почти всегда можете использовать решение AWK. Пример; у Raspberry Pi нет статов, но есть awk .
источник
Еще один совместимый с POSIX способ заключается в использовании
awk
с егоlength()
функцией, которая возвращает длину, символов в каждой строке входного файла, исключая символы новой строки. Итак, делаямы обеспечиваем
NR
добавление к немуsum
, что приводит к общему количеству символов и общему количеству новых строк, встречающихся в файле.length()
Функцияawk
принимает которая аргумент с помощью по умолчанию ,length($0)
который является для текущей всей линии.источник
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
должно быть напечатано 3, но напечатано 4.Мне нравится вариант wc сам. В паре с «bc» вы можете получить десятичные знаки в любом количестве мест, где пожелаете.
Я пытался улучшить сценарий, который у меня был, чтобы исключить столбец «размер файла» команды «ls -alh». Я не хотел просто целочисленные размеры файлов, и два десятичных знака, казалось, подходили, поэтому после прочтения этого обсуждения я пришел к приведенному ниже коду.
Я предлагаю разбить строку на точку с запятой, если вы включите это в скрипт.
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
Мой сценарий называется gpfl , для «получить длину файла изображения». Я использую его после выполнения mogrify для файла в imagemagick, перед открытием или повторной загрузкой изображения в программе просмотра JPEG с графическим интерфейсом.
Я не знаю, как это оценивается как «ответ», поскольку он многое заимствует из того, что уже было предложено и обсуждено. Так что я оставлю это там.
BZT
источник
wc
читает последний блок файла, на случай, еслиstat.st_size
это только приблизительное значение (как для Linux/proc
и/sys
файлов). Я думаю, что они решили не делать основной комментарий более сложным, когда добавили эту логику на пару строк ниже: lingrok.org/xref/coreutils/src/wc.c#246Самый быстрый и простой (ИМО) метод это:
источник
du
иwc
ответы , которые должны иметь отказ от ответственности НИКОГДА НЕ ЭТО в реальной жизни. Сегодня вечером я использовал свой ответ в реальном приложении и подумал, что им стоит поделиться. Я думаю, что у всех нас есть наше мнение пожимает плечами .