我在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
来自哪里?
答案 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