我想运行find
命令,该命令将找到某个文件列表,然后遍历该文件列表以运行某些操作。我还想查找该列表中所有文件的总大小。
我想先将文件列表设为第一,然后再进行其他操作。有没有一种简单的方法可以报告列表中所有文件的总大小?
本质上,我试图在下面的代码片段中找到'total_size'变量的单行代码:
#!/bin/bash
loc_to_look='/foo/bar/location'
file_list=$(find $loc_to_look -type f -name "*.dat" -size +100M)
total_size=???
echo 'total size of all files is: '$total_size
for file in $file_list; do
# do a bunch of operations
done
答案 0 :(得分:39)
您应该只需将$file_list
传递给du
:
du -ch $file_list | tail -1 | cut -f 1
du
选项:
-c
显示总计-h
人类可读(即17M) du
将为每个文件打印一个条目,然后是总计(-c
),因此我们使用tail -1
修剪到最后一行cut -f 1
将该行修剪为仅第一列。
答案 1 :(得分:18)
这里解释的方法有隐藏的bug。当文件列表很长时,它超出了shell命令大小的限制。最好使用du:
find <some_directories> <filters> -print0 | du <options> --files0-from=- --total -s|tail -1
find产生空结束文件列表,du从stdin获取并计数。 这与shell命令大小限制无关。 当然,您可以添加到某些开关以获取逻辑文件大小,因为默认情况下du告诉您物理空间文件将占用多少。
但我认为这对程序员来说不是问题,但对于unix管理员来说:)然后对于stackoverflow来说这是不可能的。
答案 2 :(得分:2)
此代码将所有文件中的所有字节与所有文件相加(它排除了所有目录......显然它们每个文件夹/目录只有8kb)
cd /; find -type f -exec ls -s \; | awk '{sum+=$1;} END {print sum/1000;}'
注意:以root身份执行。结果以兆字节为单位。
答案 3 :(得分:1)
@Znik提供的方法有助于解决文件列表过长时遇到的错误。
但是,在Solaris(它是Unix)上,du
没有-c
或--total
选项,因此似乎需要一个计数器来累积文件大小
此外,如果您的文件名包含特殊字符,则通过管道(Properly escaping output from pipe in xargs )的使用不会很好。
基于最初的问题,以下内容可在Solaris上运行(对变量的创建方式进行了小的修改):
file_list=($(find $loc_to_look -type f -name "*.dat" -size +100M))
printf '%s\0' "${file_list[@]}" | xargs -0 du -k | awk '{total=total+$1} END {print total}'
输出在KiB中。
答案 4 :(得分:0)
ls -l | tr -s ' ' | cut -d ' ' -f <field number>
是我经常使用的东西。
第5个字段是大小。将该命令放在for循环中并将大小添加到累加器中,您将获得目录中所有文件的总大小。比学习AWK更容易。另外,在命令替换部分,您可以grep来限制您要查找的内容(^ - 用于文件,等等。)
total=0
for size in $(ls -l | tr -s ' ' | cut -d ' ' -f 5) ; do
total=$(( ${total} + ${size} ))
done
echo ${total}
答案 5 :(得分:0)
du
的问题在于,它也增加了目录节点的大小。当您只想总结文件大小时,这是一个问题。 (顺便说一句,du
没有选择忽略目录的选项,我感到很奇怪。)
为了(递归)添加当前目录下文件的大小,我使用以下命令:
ls -laUR | grep -e "^\-" | tr -s " " | cut -d " " -f5 | awk '{sum+=$1} END {print sum}'
工作方式:它以递归方式列出所有文件("R"
,包括显示文件大小("a"
)的隐藏文件("l"
)且不排序({{ 1}})。 (当目录中有许多文件时,可能会发生这种情况。)然后,我们仅保留以“-”开头的行(这些是常规文件,因此我们忽略目录和其他内容)。然后,我们将随后的空格合并为一个,以使"U"
的表格对齐输出的各行成为每行中以空格分隔的字段列表。然后,我们ls
每行的第五个字段,该字段存储文件大小。 cut
脚本将这些值加到awk
变量中并打印结果。