如何编写一个脚本,对于每个参数,脚本应显示目录中最大的项目及其大小。像这样的东西:
[user]$ maxls /boot 2> /dev/null | sort -n
1024 /boot/grub2/themes/stars
8101 /boot/grub2/pic.png
答案1
#!/bin/sh
for dir
do
[ -d "$dir" ] || continue
du -hs "$dir"/* | sort -hr | sed 1q
done
答案2
使用perl
我会选择这样的东西:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
my %biggest_file_in;
my %biggest_file_size_in;
sub max_in_path {
my ($dir) = @_;
return unless -f;
if ( -s > ( $biggest_file_size_in{$dir} // 0 ) ) {
$biggest_file_in{$dir} = $File::Find::name;
$biggest_file_size_in{$dir} = -s;
}
}
my ($path_to_search) = @ARGV;
die "Specify a path" unless $path_to_search;
foreach my $dir ( glob("$path_to_search/*") ) {
next unless -d $dir;
find( sub { max_in_path($dir) }, $dir );
print $dir, ":", $biggest_file_in{$dir}, " =>",
$biggest_file_size_in{$dir}, "\n";
}
print "Largest files in individual directories (sorted):\n";
foreach my $dir ( sort
{ $biggest_file_size_in{$b} <=> $biggest_file_size_in{$a} }
keys %biggest_file_size_in ) {
print "$dir $biggest_file_in{$dir} $biggest_file_size_in{$dir}\n";
}
注意 - 适用于指定目录下的所有目录。 (例如: myfind.pl /data
将搜索/data/*
- 但忽略 中存在的任何文件/data
);
答案3
shellzsh
对此有内置支持:
#! /bin/zsh -
zmodload zsh/stat &&
for dir {
largest=(${dir:-.}/**/*(NDOL[1]))
(($#largest)) || largest=${dir:-.}
zstat -A size +size -- "$largest" &&
print -r -- $size $largest
}
答案4
# m_all [dir=.]...: lists the biggest file in *all* the directories.
# du options can be specified using $DU_OPTS; the recommend value is '-h'.
m_all(){ find "$@" -type f -print0 | du $DU_OPTS --files0-from=-; }
# maxls: for each argument, list the biggest $maxls_n items.
# If $maxls_n is undefined or empty, use 1.
# Additional arguments to pass to m_all can be defined in the array mallargs; see examples below.
maxls(){ local i; for i; do m_all "$i" "${mallargs[@]}" | sort -h | tail -n "${maxls_n:-1}"; done; }
#_Example:
# list the biggest file for /bin and /usr respectively
maxls /bin /usr
# list the biggest 5 files for /home and /root
maxls_n=5 maxls /home /root
# Let maxls count only *.avi, *.svg and *.mp4:
mallargs=(-iregex '.*\.\(avi\|svg\|mp4\).*')
# And run it against ~/Anime
maxls ~/Anime; mallagrs=() # clear that setting
# And use m_all to list the biggest five logs:
DU_OPTS=-h m_all /var -name '*.log*' | sort -h | tail -n 5
您甚至可以添加find
过滤器!
编辑: 为每个添加。感谢 RobertL 指出了这一点。和文档。
如果您希望将其作为脚本,请创建一个新文件,其中包含#!/bin/bash
,将这些行复制到(){
其中,然后添加maxls "$@"
.但就我个人而言,我不喜欢~/bin
用超级琐碎的脚本来填充我的脚本。
说明/变更日志
从示例中我们可以看到子目录中的文件,并且使用额外的sort -h
.由于整个目录绝对不小于其中包含的文件,因此我得出结论项目仅限于文件。
从此时起,我得到了最初的解决方案,现在称为m_all
.除非我们对它们进行排序,否则我们无法知道哪些是最大的,因此tail
在最初的示例中添加了额外的传递。
经过一些修补,这是版本 3,但这有问题,因为提问者想要对于每个参数。我将其重命名为m_all
,留下一个名为 的包装器,maxls
因为我认为旧的包装器仍然有一些用途,并且我想最小化我的更改(v4)。正如我一贯所做的那样,我留下了一些开关来改变它的行为。之后,如您所见,添加了文档 (v5-7)。
请注意,随着foreach行为,在整个事情完成后使用任何tail
或通常是没有意义的。每次获得这些输出时都sort
必须使用。确实会打印给定每个文件的最后几行,但这会使代码变得超长。sort
tail