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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:41:07  来源:igfitidea点击:

Get total size of a list of files in UNIX

bashshellunix

提问by HotDogCannon

I want to run a findcommand 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_listto du:

您应该可以简单地传递$file_listdu

du -ch $file_list | tail -1 | cut -f 1

duoptions:

du选项:

  • -cdisplay a total
  • -hhuman readable (i.e. 17M)
  • -c显示总计
  • -h人类可读(即 17M)

duwill print an entry for each file, followed by the total (with -c), so we use tail -1to trim to only the last line and cut -f 1to 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), dudoes not have the -cor --totaloption, so it seems there is a need for a counter to accumulate file sizes.

然而,在 Solaris(这是一个 Unix)上,du没有-cor--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 '%s
ls -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 duis 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 duhas 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 lsbecomes a single-space-separated list of fields in each line. Then we cutthe 5th field of each line, which stores the file size. The awkscript sums these values up into the sumvariable and prints the results.

工作原理:它递归地列出所有文件 ( "R"),包括隐藏文件 ( "a"),显示其文件大小 ( "l"),但不对其进行排序 ( "U")。(当目录中有很多文件时,这可能会发生。)然后,我们只保留以“-”开头的行(这些是常规文件,因此我们忽略目录和其他内容)。然后我们将后续空格合并为一个,以便表​​格对齐输出的行ls成为每行中单个空格分隔的字段列表。然后cut是每行的第 5 个字段,它存储文件大小。该awk脚本总结这些值成的sum变量,并打印出结果。