Подтвердить что ты не робот

Как проверить размер файла?

У меня есть 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
4b9b3361

Ответ 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

тоже будет работать.