bash 获取 UNIX 中文件列表的总大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21989860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get total size of a list of files in UNIX
提问by HotDogCannon
I want to run a find
command that will find a certain list of files and then iterate through that list of files to run some operations. I also want to find the total size of all the files in that list.
我想运行一个find
命令来查找某个文件列表,然后遍历该文件列表以运行一些操作。我还想找到该列表中所有文件的总大小。
I'd like to make the list of files FIRST, then do the other operations. Is there an easy way I can report just the total size of all the files in the list?
我想首先制作文件列表,然后进行其他操作。有没有一种简单的方法可以报告列表中所有文件的总大小?
In essence I am trying to find a one-liner for the 'total_size' variable in the code snippet below:
本质上,我试图在下面的代码片段中为“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
回答by sanmiguel
You should simply be able to pass $file_list
to du
:
您应该可以简单地传递$file_list
给du
:
du -ch $file_list | tail -1 | cut -f 1
du
options:
du
选项:
-c
display a total-h
human readable (i.e. 17M)
-c
显示总计-h
人类可读(即 17M)
du
will print an entry for each file, followed by the total (with -c
), so we use tail -1
to trim to only the last line and cut -f 1
to trim that line to only the first column.
du
将为每个文件打印一个条目,然后是总数(带-c
),因此我们使用tail -1
仅修剪到最后一行并将cut -f 1
该行仅修剪到第一列。
回答by Znik
Methods explained here have hidden bug. When file list is long, then it exceeds limit of shell comand size. Better use this one using du:
这里解释的方法有隐藏的错误。当文件列表很长时,它超过了 shell 命令大小的限制。最好使用 du 使用这个:
find <some_directories> <filters> -print0 | du <options> --files0-from=- --total -s|tail -1
find produces null ended file list, du takes it from stdin and counts. this is independent of shell command size limit. Of course, you can add to du some switches to get logical file size, because by default du told you how physical much space files will take.
find 生成空结尾的文件列表,du 从 stdin 中获取它并进行计数。这与 shell 命令大小限制无关。当然,您可以向 du 添加一些开关来获取逻辑文件大小,因为默认情况下 du 会告诉您文件将占用多少物理空间。
But I think it is not question for programmers, but for unix admins :) then for stackoverflow this is out of topic.
但我认为这不是程序员的问题,而是 unix 管理员的问题 :) 那么对于 stackoverflow 来说,这是不合时宜的。
回答by Alex Konrad Ke?ler
This code adds up all the bytes from the trusty ls for all files (it excludes all directories... apparently they're 8kb per folder/directory)
此代码将来自所有文件的可信赖 ls 的所有字节相加(它不包括所有目录......显然它们每个文件夹/目录为 8kb)
cd /; find -type f -exec ls -s \; | awk '{sum+=;} END {print sum/1000;}'
Note:Execute as root. Result in megabytes.
注意:以 root 身份执行。结果以兆字节为单位。
回答by Richard
ls -l | tr -s ' ' | cut -d ' ' -f <field number>
is something I use a lot.
ls -l | tr -s ' ' | cut -d ' ' -f <field number>
是我经常使用的东西。
The 5th field is the size. Put that command in a for loop and add the size to an accumulator and you'll get the total size of all the files in a directory. Easier than learning AWK. Plus in the command substitution part, you can grep to limit what you're looking for (^- for files, and so on).
第 5 个字段是大小。将该命令放入 for 循环并将大小添加到累加器中,您将获得目录中所有文件的总大小。比学习 AWK 更容易。另外,在命令替换部分,您可以使用 grep 来限制您要查找的内容(^- 用于文件等)。
total=0
for size in $(ls -l | tr -s ' ' | cut -d ' ' -f 5) ; do
total=$(( ${total} + ${size} ))
done
echo ${total}
回答by Cyril
The method provided by @Znik helps with the bug encountered when the file list is too long.
@Znik 提供的方法有助于解决文件列表太长时遇到的错误。
However, on Solaris (which is a Unix), du
does not have the -c
or --total
option, so it seems there is a need for a counter to accumulate file sizes.
然而,在 Solaris(这是一个 Unix)上,du
没有-c
or--total
选项,所以似乎需要一个计数器来累积文件大小。
In addition, if your file names contain special characters, this will not go too well through the pipe (Properly escaping output from pipe in xargs ).
此外,如果您的文件名包含特殊字符,这将不会很好地通过管道(在 xargs 中正确转义管道的输出 )。
Based on the initial question, the following works on Solaris (with a small amendment to the way the variable is created):
基于最初的问题,以下适用于 Solaris(对创建变量的方式稍作修改):
file_list=($(find $loc_to_look -type f -name "*.dat" -size +100M))
printf '%sls -laUR | grep -e "^\-" | tr -s " " | cut -d " " -f5 | awk '{sum+=} END {print sum}'
' "${file_list[@]}" | xargs -0 du -k | awk '{total=total+} END {print total}'
The output is in KiB.
输出单位为 KiB。
回答by Csongor Halmai
The problem with du
is that it adds up the size of the directory nodes as well. It is an issue when you want to sum up only the file sizes. (Btw., I feel strange that du
has no option for ignoring the directories.)
问题du
在于它也增加了目录节点的大小。当您只想总结文件大小时,这是一个问题。(顺便说一句,我觉得很奇怪,du
无法忽略目录。)
In order to add the size of files under the current directory (recursively), I use the following command:
为了添加当前目录下文件的大小(递归),我使用以下命令:
##代码##How it works: it lists all the files recursively ("R"
), including the hidden files ("a"
) showing their file size ("l"
) and without ordering them ("U"
). (This can be a thing when you have many files in the directories.) Then, we keep only the lines that start with "-" (these are the regular files, so we ignore directories and other stuffs). Then we merge the subsequent spaces into one so that the lines of the tabular aligned output of ls
becomes a single-space-separated list of fields in each line. Then we cut
the 5th field of each line, which stores the file size. The awk
script sums these values up into the sum
variable and prints the results.
工作原理:它递归地列出所有文件 ( "R"
),包括隐藏文件 ( "a"
),显示其文件大小 ( "l"
),但不对其进行排序 ( "U"
)。(当目录中有很多文件时,这可能会发生。)然后,我们只保留以“-”开头的行(这些是常规文件,因此我们忽略目录和其他内容)。然后我们将后续空格合并为一个,以便表格对齐输出的行ls
成为每行中单个空格分隔的字段列表。然后cut
是每行的第 5 个字段,它存储文件大小。该awk
脚本总结这些值成的sum
变量,并打印出结果。