如何使用 Bash 检查文件的大小?

我有一个检查0大小的脚本,但是我认为必须有一个更简单的方法来检查文件大小。例如,file.txt通常是100kB; 如果一个脚本小于90kB (包括0) ,我如何进行脚本检查,并使其 Wget成为一个新的副本,因为在这种情况下文件是损坏的?

我现在用的..。

if [ -n file.txt ]
then
echo "everything is good"
else
mail -s "file.txt size is zero, please fix. " myemail@gmail.com < /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
303494 次浏览

[ -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

在这种情况下,听起来这就是你想要的。

但是仅供参考,如果你想知道文件使用了多少磁盘空间,你可以使用 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的东西开始,在 BSDMac OS X上,你可以从类似 stat -f '%z' file.txt的东西开始。

带有 AWK和双括号的替代解决方案:

FILENAME=file.txt
SIZE=$(du -sb $FILENAME | awk '{ print $1 }')


if ((SIZE<90000)) ; then
echo "less";
else
echo "not less";
fi

如果您的 find处理这种语法,您可以使用它:

find -maxdepth 1 -name "file.txt" -size -90k

当且仅当 file.txt的大小小于90k 时,这将输出 file.txt到 stdout。如果 file.txt的大小小于90k,则执行脚本 script:

find -maxdepth 1 -name "file.txt" -size -90k -exec script \;

对于在 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 上就不行了:

  • 在 Mac 中,du没有 -b选项,而且 BLOCKSIZE = 1技巧不起作用(“最小块大小是512”,这会导致错误的结果)

  • cut -d' ' -f1不起作用,因为在 Mac 上,数字可能是右对齐的,前面填充了空格。

因此,如果您需要一些灵活的东西,它要么是 perl-s操作符,要么是通过管道连接到 awk '{print $1}'wc -c(awk 将忽略前面的空白)。

当然,对于原来问题的其余部分,使用 -lt(或 -gt)操作符:

if [ $size -lt $your_wanted_size ]; then等。

stat 还可以检查文件大小。有些方法绝对是更好的: 如果您只需要使用 -s来确定文件是否为空,那么使用 -s比使用其他任何方法都要容易。如果你想要 找到文件的一个大小,那么 find是肯定的方式去。

我也非常喜欢使用 du来获得以 kb 为单位的文件大小,但是,对于字节,我会使用 stat:

size=$(stat -f%z $filename) # BSD stat


size=$(stat -c%s $filename) # GNU stat?

如果你只是在寻找一个文件的大小:

cat $file | wc -c

输出样本:

203233

这在 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
}

根据尼古尔夫的回答,

find "file.txt" -size -90k

当且仅当 file.txt的大小小于90K,并且

find "file.txt" -size -90k -exec command \;

will execute the command command if file.txt has a size less than 90K.  I have tested this on Linux.  From find(1),

…  Command-line arguments following (the -H, -L and -P options) are taken to be names of files or directories to be examined, up to the first argument that begins with ‘-’, …

(emphasis added).

用途:

python -c 'import os; print (os.path.getsize("... filename ..."))'

对于 Python 的所有风格,它都是可移植的,并且避免了 stat方言的变化。

ls -l $file | awk '{print $6}'

假设 ls 命令报告的文件大小位于列 # 6

我会用 du--threshold来做这个。不确定这个选项是否在 du的所有版本中都可用,但它是在 GNU 的版本中实现的。

引自 嘟(1)手册:

-t, --threshold=SIZE
exclude entries smaller than SIZE if positive, or entries greater
than SIZE if negative

下面是我的解决方案,使用 du --threshold=作为 OP 的用例:

THRESHOLD=90k
if [[ -z "$(du --threshold=${THRESHOLD} file.txt)" ]]; then
mail -s "file.txt size is below ${THRESHOLD}, please fix. " myemail@gmail.com < /dev/null
mv -f /root/tmp/file.txt /var/www/file.txt
fi

这样做的好处是,du可以接受一个已知格式的参数,无论是 10K10MiB还是任何你感觉舒服的格式,你不需要手动转换格式/单位,因为 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.

好吧,如果你用的是 Mac 电脑,这样做: Stat-f% z”/用户/示例/config.log” 就是这样!