在 bash 外壳中添加文件大小



我写了一个 shell 脚本,它将目录作为 arg 并打印文件名和大小,我想了解如何将文件大小相加并存储它们,以便我可以在循环后打印它们。我已经尝试了一些事情,但到目前为止还没有取得任何进展,有什么想法吗?

#!/bin/bash
echo "Directory <$1> contains the following files:"
let "x=0"
TEMPFILE=./count.tmp
echo 0 > $TEMPFILE
ls $1 |
while read file
do
if [ -f $1/$file ]
then
echo "file: [$file]"
stat -c%s $file > $TEMPFILE
fi
cat $TEMPFILE
done
echo "number of files:"
cat ./count.tmp

帮助将不胜感激。

代码中的许多问题:

  • 不要解析 ls
  • 在大多数情况下引用变量
  • 不要在不需要临时文件时使用
  • 为此使用已经制作的工具,例如du(请参阅注释)

假设你只是想练习这个和/或想做du已经做的其他事情,你应该将语法更改为类似

#!/bin/bash
dir="$1"
[[ $dir == *'/' ]] || dir="$dir/"
if [[ -d $dir ]]; then
echo "Directory <$1> contains the following files:"
else
echo "<$1> is not a valid directory, exiting"
exit 1
fi
shopt -s dotglob
for file in "$dir"*; do
if [[ -f $file ]]; then
echo "file: [$file]"
((size+=$(stat -c%s "$file")))
fi
done
echo "$size"

注意:

  • 您不必在 bash 中预先分配变量,$size假定为 0
  • 您可以将(())用于不需要小数位的数学运算。
  • 您可以使用 globs (*) 获取特定目录中的所有文件(包括目录、符号链接等)(以及 globstar**递归)
  • shopt -s dotglob是必需的,因此它在 glob 匹配中包含隐藏的.whatever文件。

您可以使用ls -l来查找文件大小:

echo "Directory $1 contains the following:"
size=0
for f in "$1"/*; do
if [[ ! -d $f ]]; then
while read _ _ _ _ bytes _; do
if [[ -n $bytes ]]; then
((size+=$bytes))
echo -e "tFile: ${f/$1//} Size: $bytes bytes"
fi
done < <(ls -l "$f")
fi
done
echo "$1 Files total size: $size bytes"

在这里解析大小ls结果是可以的,因为字节大小将始终在第 5 个字段中找到。

如果您知道系统上ls的日期戳格式,并且可移植性并不重要,则可以解析ls,以便在单个while read循环中可靠地查找大小和文件。

echo "Directory $1 contains the following:"
size=0
while read _ _ _ _ bytes _ _ _ file; do
if [[ -f $1/$file ]]; then
((size+=$bytes))
echo -e "tFile: $file Size: $bytes bytes"
fi
done < <(ls -l "$1")
echo "$1 Files total size: $size bytes"

注意:这些解决方案不包括隐藏文件。 为此使用ls -la

根据需要或偏好,ls还可以使用-h--block-size=SIZE等选项以多种不同格式打印尺寸。

#!/bin/bash
echo "Directory <$1> contains the following files:"
find ${1}/* -prune -type f -ls | 
awk '{print; SIZE+=$7} END {print ""; print "total bytes: " SIZE}'

将 find与 -prune(因此它不会递归到子目录中)和 -type f(因此它只会列出文件而不列出符号链接或目录)和-ls(因此它会列出文件)一起使用。

通过管道将输出转换为 awk 和

对于每一行,打印整行(打印;替换为print $NF仅打印每行的最后一项,即包含目录的文件名)。还要将第 7 个字段的值(即文件大小(在我的 find 版本中)添加到变量 SIZE。

处理完所有行 (END) 后,打印计算出的总大小。

相关内容

  • 没有找到相关文章

最新更新