Как проверить размер файла?
У меня есть script, который проверяет размер 0, но я думал, что должен быть более простой способ проверить размеры файлов. То есть file.txt
обычно равно 100k; как сделать script проверить, если оно меньше 90k (включая 0), и сделать его wget новой копией, потому что файл поврежден в этом случае.
То, что я сейчас использую.
if [ -n file.txt ]
then
echo "everything is good"
else
mail -s "file.txt size is zero, please fix. " [email protected] < /dev/null
# Grab wget as a fallback
wget -c https://www.server.org/file.txt -P /root/tmp --output-document=/root/tmp/file.txt
mv -f /root/tmp/file.txt /var/www/file.txt
fi
Ответы
Ответ 1
[ -n file.txt ]
не проверяет его размер, он проверяет, что строка file.txt
имеет ненулевую длину, поэтому она всегда будет успешной.
Если вы хотите сказать, что "размер отличен от нуля", вам нужно [ -s file.txt ]
.
Чтобы получить размер файла, вы можете использовать wc -c
для получения размера (длины файла) в байтах:
file=file.txt
minimumsize=90000
actualsize=$(wc -c <"$file")
if [ $actualsize -ge $minimumsize ]; then
echo size is over $minimumsize bytes
else
echo size is under $minimumsize bytes
fi
В этом случае это похоже на то, что вы хотите.
Но FYI, если вы хотите узнать, сколько дискового пространства используется данным файлом, вы можете использовать du -k
для получения размера (используемого дискового пространства) в килобайтах:
file=file.txt
minimumsize=90
actualsize=$(du -k "$file" | cut -f 1)
if [ $actualsize -ge $minimumsize ]; then
echo size is over $minimumsize kilobytes
else
echo size is under $minimumsize kilobytes
fi
Если вам нужно больше контролировать выходной формат, вы также можете посмотреть stat
. В Linux вы начнете с чего-то вроде stat -c '%s' file.txt
, а на BSD/Mac OS X, например, stat -f '%z' file.txt
.
Ответ 2
Меня удивляет, что никто не упомянул stat
, чтобы проверить размер файла. Некоторые методы определенно лучше: использование -s
, чтобы выяснить, пуст ли файл или нет, проще, чем что-либо еще, если это все, что вы хотите. И если вы хотите найти файлы размером, то find
- это, безусловно, путь.
Мне также нравится du
, чтобы получить размер файла в kb, но для байтов я использовал бы stat
:
size=$(stat -f%z $filename) # BSD stat
size=$(stat -c%s $filename) # GNU stat?
Ответ 3
альтернативное решение с awk и двойной скобкой:
FILENAME=file.txt
SIZE=$(du -sb $FILENAME | awk '{ print $1 }')
if ((SIZE<90000)) ; then
echo "less";
else
echo "not less";
fi
Ответ 4
Если ваш find
обрабатывает этот синтаксис, вы можете его использовать:
find -maxdepth 1 -name "file.txt" -size -90k
Это приведет к выводу file.txt
в stdout тогда и только тогда, когда размер file.txt
меньше 90k. Для выполнения script script
, если file.txt
имеет размер меньше 90k:
find -maxdepth 1 -name "file.txt" -size -90k -exec script \;
Ответ 5
Если вы ищете только размер файла:
$ cat $file | wc -c
> 203233
Ответ 6
Это работает как в linux, так и в macos
function filesize
{
local file=$1
size=`stat -c%s $file 2>/dev/null` # linux
if [ $? -eq 0 ]
then
echo $size
return 0
fi
eval $(stat -s $file) # macos
if [ $? -eq 0 ]
then
echo $st_size
return 0
fi
return -1
}
Ответ 7
Для получения размера файла как в Linux, так и в Mac OS X (и, предположительно, других BSD), вариантов не так много, и большинство из предложенных здесь функций будут работать только в одной системе.
Учитывая f=/path/to/your/file
,
что работает как в Linux, так и в Mac Bash:
size=$( perl -e 'print -s shift' "$f" )
или
size=$( wc -c "$f" | awk '{print $1}' )
Другие ответы отлично работают в Linux, но не в Mac:
-
du
не имеет опции -b
в Mac, а трюк BLOCKSIZE = 1 не работает ( "минимальный размер блока равен 512", что приводит к неправильному результату)
-
cut -d' ' -f1
не работает, потому что на Mac число может быть выровнено по правому краю, дополнено пробелами впереди.
Итак, если вам нужно что-то гибкое, это либо оператор perl
-s
, либо wc -c
с номером awk '{print $1}'
(awk будет игнорировать начальное свободное пространство).
И, конечно же, в отношении остальной части вашего исходного вопроса используйте оператор -lt
(или -gt
):
if [ $size -lt $your_wanted_size ]; then
и т.д.
Ответ 8
python -c 'import os; print (os.path.getsize("... filename ..."))'
портативный, все вкусы питона, избегает изменения диалектов статов
Ответ 9
stat, похоже, делает это с наименьшим количеством системных вызовов:
$ set debian-live-8.2.0-amd64-xfce-desktop.iso
$ strace stat --format %s $1 | wc
282 2795 27364
$ strace wc --bytes $1 | wc
307 3063 29091
$ strace du --bytes $1 | wc
437 4376 41955
$ strace find $1 -printf %s | wc
604 6061 64793
Ответ 10
На основе ответа gniourf_gniourfs
find "file.txt" -size -90k
будет писать file.txt
в stdout тогда и только тогда, когда размер file.txt
меньше 90K, а
find "file.txt" -size -90k -exec command \;
выполнит команду command
, если file.txt
имеет размер меньше 90K.
Я тестировал это на Linux.
Из find(1)
,
... Следующие аргументы командной строки (параметры -H
, -L
и -P
) считаются именами файлов или, которые нужно изучить, вплоть до первого аргумента, который начинается с '-,...
(выделено курсивом).
Ответ 11
ls -l $file | awk '{print $6}'
предполагая, что команды команды ls filesize в столбце # 6
Ответ 12
Я бы использовал du
--threshold
для этого. Не уверен, что эта опция доступна во всех версиях du
но она реализована в версии GNU.
Цитирование из руководства du (1):
-t, --threshold=SIZE
exclude entries smaller than SIZE if positive, or entries greater
than SIZE if negative
Вот мое решение, использующее du --threshold=
для du --threshold=
использования OP:
THRESHOLD=90k
if [[ -z "$(du --threshold=${THRESHOLD} file.txt)" ]]; then
mail -s "file.txt size is below ${THRESHOLD}, please fix. " [email protected] < /dev/null
mv -f /root/tmp/file.txt /var/www/file.txt
fi
Преимущество этого в том, что du
может принять аргумент для этой опции в известном формате - либо в человеческом, как в 10K
, 10MiB
либо как вам удобно - вам не нужно вручную преобразовывать форматы/единицы, поскольку du
обрабатывает тот.
Для справки, вот объяснение этого аргумента SIZE
со страницы руководства:
The SIZE argument is an integer and optional unit (example: 10K is
10*1024). Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers
of 1000). Binary prefixes can be used, too: KiB=K, MiB=M, and so on.
Ответ 13
Хорошо, если вы на Mac, сделайте это:
stat -f %z "/Users/Example/config.log"
Это!
Ответ 14
В bash
if [ -s file.txt ]; then
...
fi
тоже будет работать.