我将如何测量目录中文件的大小?

我有一个充满600GB文件的文件夹。 我想自动将第一个300复制到一个文件夹,其余的到另一个文件夹。 我不知道如何限制结果与ls或其中任何一个,所以我可以通过它作为一个论点…

平台是Linux …

编辑:我想移动300GB,而不是前300个文件。 文件大小是任意的,sorting无关紧要。

更新:哦,第一个300GB,那么…这可能很慢,这取决于文件大小,但我喜欢练习:-)

filesize=0 for i in *; do filesize=$(stat -c "%s" "$i"); (( totalsize += filesize )); if [[ $totalsize < 322122547200 ]]; then mv "$i" first_300/ else mv "$i" the_rest/ fi done 

希望这个int的大小没有问题。


如果你的意思是把它们分成有300个文件的文件夹,也许你想要类似下面的东西:

 folder=0 counter=0 for i in *; do mv $i foo_$folder/ if [[ $(( counter % 10 )) -eq 0 ]]; then (( folder++ )); fi (( counter++ )) done 

尽pipe这可能不如一些查找命令那么快。 如果你只是想做第一个300命令,你可以使用相同的计数器策略,但使用一会儿$ counterlele 300。

这是获得几乎相同的300GB分配的一种方式,

您可以执行基于du的search来查找顶级目录和文件的分布,然后通过一些试验将它们分成几乎两部分。

 find . -maxdepth 1 -type d -exec du -sk {} \; | sort -n -k 1 > list.txt 

这将给出一个KB大小的sorting列表。
你可以做一些小技巧,比如在这个列表上select一个交替的行,以便快速的分布

 awk '{if (FNR%2==1) print $2}' list.txt > list1.txt awk '{if (FNR%2==0) print $2}' list.txt > list2.txt 

一个非常粗糙的分布…

最后,如果您的文件或目录大小非常不均匀 – 与300GB分配相差甚远,
保持自己远离装箱问题 ,做一些简单的试验,在两个列表文件之间移动几行。
找出两套( du )之间的差异,并移动一个目录/文件
这大概是从较大的名单到较小的名单的一半。
这应该让你相当接近

你可以用findheadxargs来完成 。 它应该是这样的:

 find ./ -type f -print0 | head -300 | xargs -0 -I mv {} /one/folder find ./ -type f -print0 | xargs -0 -I mv {} /another/folder 

警告! 当你开始计算文件大小的时候,你可能会犯错误来测量它们的字节数,而大多数文件系统将会以块的forms分配磁盘空间。 这个块大小因磁盘而异,但通常是512的倍数。

基本上,这意味着你可以有500个文件,每个文件只有500个字节。 但是每个块分配2048字节的文件系统因此声称大约有1兆字节的磁盘空间。 是的,这是一个很大的开销。

基本上,您应该根据您使用的文件系统的块大小来整理文件大小。 这样,你可以更精确地测量它们。

那又怎么样呢? 如果块大小是2048字节,那么平均丢失字节数将是1 KB。 有300个文件,这将是大约300 KB,您将需要更多的总大小之上。 你想复制300 GB,但会有多less文件? 而且这两个磁盘使用相同的文件系统具有相同的块大小?

无论如何,错误率取决于平均文件大小。 如果你有很多巨大的文件(音乐,图像,二进制文件),误差极小。 如果您有很多小文件(如脚本,源文件和文本文件),那么错误页边距可能会轻松地为总文件大小添加另外30 GB的文件,而您没有考虑到这一点。

所以,测量文件大小并不容易…

您可以通过从ls -l提取大小或使用du命令来获得文件使用的列表:

$ cd /dirwithlotsoffiles $ du -k *

这将打印一个文件大小的列表,以千字节为单位,后跟文件名。

根据我的理解,“查找”答案会复制前300个文件,而不是前300GB。

您可以尝试使用tar及其多个卷选项

一个非常粗略的方法是循环遍历大小(ls -S)的文件,并简单地将每个备用文件移动到其中一个子目录。 这个怎么样:

 #!/usr/bin/bash dir1=path/to/dir1 dir2=path/to/dir2 a=0 for file in `ls -1S` do a=`expr $a + 1` even=`expr $a%2|bc` if [ $even -gt 0 ] then mv $file $dir1 else mv $file $dir2 fi done 

恐怕你可能不得不在这里用一些脚本来弄脏你的手。 您可以使用terminal命令ls -l轻松获取文件列表和文件大小,然后您必须编写一个脚本,通过该列表逐个拷贝文件,并保留一个计数器以loggingKB转移到目前为止。 每次检查我们是否移动了300GB的价值,如果没有,移动另一个文件。 它可能在10行或更less的Perl中可用。

您只需获取文件名列表以及每个文件的大小即可获得合理的结果。 按照最大的大小sorting文件。 然后,只需复制列表中最大的文件,将其放入目标目录的剩余空间中,然后将其从列表中删除。 重复,直到没有更多的文件适合。

然后重新开始一个新的目标目录。 重复,直到列表为空。