Ответ 1
wc -c < filename
(сокращение числа слов, -c
печатает количество байтов) - это портативное решение гарантируют обработку двоичных файлов, если явно не указано явно.
В Linux я использую stat --format="%s" FILE
, но у Solaris у меня есть доступ к команде stat. Что мне тогда использовать?
Я пишу сценарии Bash и не могу установить какое-либо новое программное обеспечение в системе.
Я уже использовал:
perl -e '@x=stat(shift);print $x[7]' FILE
или даже:
ls -nl FILE | awk '{print $5}'
Но ни один из них не выглядит разумным - запуск Perl только для получения размера файла? Или запустите 2 команды, чтобы сделать то же самое?
wc -c < filename
(сокращение числа слов, -c
печатает количество байтов) - это портативное решение гарантируют обработку двоичных файлов, если явно не указано явно.
В итоге я написал свою собственную программу (очень маленькую), чтобы отображать только размер. Дополнительная информация здесь: http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
Два самых чистых способа, на мой взгляд, с обычными инструментами Linux:
$ stat -c %s /usr/bin/stat
50000
$ wc -c < /usr/bin/wc
36912
Но я просто не хочу вводить параметры или передавать вывод только для получения размера файла, поэтому я использую свой собственный bfsize.
Даже если du
обычно печатает использование диска, а не фактический размер данных, GNU coreutils du
может печатать файл "видимый размер" в байтах:
du -b FILE
Но он не будет работать под BSD, Solaris, macOS,...
Наконец, я решил использовать расширение ls и bash:
TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}
это не очень хорошо, но по крайней мере он делает только 1 fork + execve и не полагается на вторичный язык программирования (perl/ruby /python/whatever)
Самое быстрое решение кросс-платформы (использует только single fork() для ls, не пытается подсчитать действительные символы, не создает ненужных awk, perl и т.д.).
Протестировано на MacOS, Linux - может потребоваться незначительная модификация для Solaris:
__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"
При необходимости упростите аргументы ls и отрегулируйте смещение в ${__ ln [3]}.
Примечание: будут следовать символическим ссылкам.
У BSD есть stat
с разными опциями из GNU coreutils one, но с аналогичными возможностями.
stat -f %z <file name>
Это работает на macOS (проверено 10.12), FreeBSD, NetBSD и OpenBSD.
Вы можете использовать команду find
для получения некоторого набора файлов (здесь распаковываются временные файлы). Затем вы можете использовать команду du
, чтобы получить размер файла для каждого файла в удобочитаемой форме с помощью переключателя -h
.
find $HOME -type f -name "*~" -exec du -h {} \;
ВЫВОД:
4.0K /home/turing/Desktop/JavaExmp/TwoButtons.java~
4.0K /home/turing/Desktop/JavaExmp/MyDrawPanel.java~
4.0K /home/turing/Desktop/JavaExmp/Instream.java~
4.0K /home/turing/Desktop/JavaExmp/RandomDemo.java~
4.0K /home/turing/Desktop/JavaExmp/Buff.java~
4.0K /home/turing/Desktop/JavaExmp/SimpleGui2.java~
При обработке вывода ls -n
в качестве альтернативы плохо переносимым массивам оболочки вы можете использовать позиционные аргументы, которые образуют единственный массив и являются единственными локальными переменными в стандартной оболочке. Оберните перезапись позиционных аргументов в функции, чтобы сохранить исходные аргументы в вашей script или функции.
getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE
Это разделяет вывод ln -dn
в соответствии с текущими настройками переменных среды IFS
, присваивает его позиционным аргументам и повторяет пятый. -d
обеспечивает правильную обработку каталогов, а -n
гарантирует, что имена пользователей и групп не должны быть разрешены, в отличие от -l
. Кроме того, имена пользователей и групп, содержащие пробелы, могут теоретически нарушить ожидаемую структуру строки; они обычно запрещены, но эта возможность все еще заставляет программиста остановиться и подумать.
Первый пример Perl для меня не выглядит необоснованным.
По причинам, подобным этому, я перешел от написания сценариев оболочки (в bash/sh и т.д.) для записи всех, кроме самых тривиальных скриптов в Perl. Я обнаружил, что мне приходится запускать Perl для определенных требований, и, когда я делал это все больше и больше, я понял, что сценарии на Perl, вероятно, были более мощными (с точки зрения языка и широкого набора библиотек, доступных через CPAN) и более эффективным способом достижения желаемого.
Обратите внимание, что другие языки скриптинга (например, python/ruby), без сомнения, будут иметь аналогичные возможности, и вы можете оценить их для своих целей. Я только обсуждаю Perl, так как язык, который я использую и знакомый.
Как насчет du -s <file>
?
Если вы используете find
из GNU fileutils:
size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )
К сожалению, другие реализации find
обычно не поддерживают -maxdepth
, а не -printf
. Это относится, например, к примеру. Solaris и macOS find
.
если у вас есть Perl на Solaris, а затем используйте его. В противном случае, ls с awk - ваш лучший лучший выбор, так как у вас нет статистики или ваша находка не найдена GNU.
В Solaris, который я использовал, есть трюк, если вы запрашиваете размер более одного файла, он возвращает только общий размер без имен, поэтому включите пустой файл, например /dev/null, в качестве второго файла:
например, команда fileyouwant/dev/null
Я не могу вспомнить, какая команда размера работает для ls/wc/etc - к сожалению, у меня нет камеры Solaris, чтобы проверить ее.
на linux вы можете использовать du -h $FILE
, это тоже работает на солярии?
Вы попробовали du -ks | awk '{print $1 * 1024}'. Это может сработать.