bash脚本:计算文件的总和大小

时间:2018-04-23 08:38:22

标签: linux bash shell awk ls

我在Linux上工作,需要计算目录中某些文件的总和大小。

我已经编写了一个名为cal.sh的bash脚本,如下所示:

#!/bin/bash

while IFS='' read -r line || [[ -n "$line" ]]; do
    echo $line
done<`ls -l | grep opencv | awk '{print $5}'`

但是,当我执行此脚本./cal.sh时,出现错误:

./cal.sh: line 6: `ls -l | grep opencv | awk  '{print $5}'`: ambiguous redirect

如果我用sh cal.sh执行它,它似乎工作但我会在输出结束时得到一些奇怪的消息:

25
31
385758: File name too long

为什么sh cal.sh似乎有效? File name too long来自哪里?

3 个答案:

答案 0 :(得分:3)

或者,您可以这样做:

du -cb *opencv* | awk 'END{print $1}'

选项-b将以字节为单位显示每个文件,-c将打印总大小。

答案 1 :(得分:2)

我建议不要使用该管道来获取所需文件的大小 - 通常解析ls是您应该避免的。相反,您只需使用*opencv*获取文件,stat即可打印尺寸:

stat -c %s *opencv*

格式说明符%s以字节为单位打印每个文件的大小。

您可以将其传输到awk以获得总和:

stat -c %s *opencv* | awk '{ sum += $0 } END { if (sum) print sum }'

if确保没有输入=&gt;没有输出。

答案 2 :(得分:2)

最终,正如其他答案所指出的那样,解析ls的输出并不是一个好主意,因为它可能因系统而异。但是值得知道为什么脚本不起作用。

模糊重定向错误是因为您需要围绕ls命令的引号,例如:

while IFS='' read -r line || [[ -n "$line" ]]; do
  echo $line
done < "`ls -l | grep opencv | awk '{print $5}'`"

但是这仍然不能做你想要的。 “&lt;” operator期望一个文件名,这里定义为ls命令的输出。但是您不想读取文件,而是想要读取ls的输出。为此你可以使用“&lt;&lt;&lt;&lt;&lt;运算符,也称为“here string”,即:

while IFS='' read -r line || [[ -n "$line" ]]; do
    echo $line
done <<< "`ls -l | grep opencv | awk '{print $5}'`"

这可以按预期工作,但有一些缺点。当使用“here string”时,命令必须首先完全执行,然后将所述命令的输出存储在临时变量中。如果命令执行时间很长或输出很大,则可能会出现问题。

恕我直言,逐行迭代命令输出的最佳和最标准的方法如下:

ls -l | grep opencv | awk '{print $5} '| while read -r line ; do
    echo "line: $line"
done