我希望在计算目录大小时列出目录,并使用简单的命令打印整个目录LS和awk,可以很好地控制列表和我希望显示的内容:
ls -AlhF /usr | awk '{print $6, $7, $8, "\011", $9 }'
但我想更进一步,要获取文件夹或文件的大小,请使用 $9 和命令杜-s像这样的东西:
ls -AlhF /usr | awk '{print $6, $7, $8, "\011", $9, du -s /usr/$9 }'
我尝试了很多方法来编写它,使用反引号、双引号,但最终总是会出现错误或不需要的结果。
答案1
ls
要回答这个问题并暂时忽略有关解析 的输出的问题,要获取 中命令的输出(stdout) awk
,您可以执行以下操作:
cmd="that command"
output=""
while ((cmd | getline line) > 0)
output = output line RS
status = close(cmd)
退出状态如何编码在地位变量因一种awk
实现而异。您可以信赖的是,当且仅当cmd
成功时它才会为 0。
getline
启动一个 shell(通常是 POSIX shell,但在某些系统上,可能是 Bourne shell)来解析该命令行。因此,正确引用其中的数据非常重要。最好是使用单引号,这是最安全的。
在这里,由于输出无论如何都是一行(您的方法无法处理带有任何空格字符的文件名,更不用说换行符了),因此您只需要执行一个操作getline
:
awk -v q="'" '
function shquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
{
cmd = "du -sk " shquote("/usr/" $9)
cmd | getline du_output
status = close(cmd)
}'
getline
如果您在没有变量名的情况下调用,则它会进行设置$0
,以便更轻松地提取磁盘使用情况:
DIR=/usr export DIR
LC_ALL=C ls -l -- "$DIR" | awk -v q="'" '
function shquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
{
date = $6 " " $7 " " $8
name = $9
cmd = "du -sk " shquote(ENVIRON["DIR"] (ENVIRON["DIR"] ~ /^\/*$/ ? "" : "/") name)
cmd | getline
disk_usage = $1
print date "\t" name "\t" disk_usage
}'
答案2
ls -AlhF /usr | awk '{print "echo "$6" "$7" "$8" \011 "$9" $(du -s /usr/"$9")" }' | sh
使用 awk 构建 echo 和 du 命令,然后通过管道到 sh 执行它。
答案3
这是一个perl
实现不依赖于解析输出ls -l
(本质上是不可靠的),并且可以轻松修改为使用所需的任何日期或大小输出格式。
将其保存到文件中,使其可执行并以/path/to/script /usr
.该脚本需要一个或多个目录名称参数。
#!/usr/bin/perl
use strict;
use Date::Format;
if ($#ARGV < 0) { die "Missing directory argument" };
foreach my $dir (@ARGV) {
$dir =~ s:/+$::; # strip trailing /
opendir(my $dh, $dir) || die "Can't opendir $dir: $!";
while (readdir $dh) {
next if (m/^\.{1,2}$/); # skip . and .. entries
my $mtime=(stat("$dir/$_"))[9]; # extract mtime field from stat
my $mtime_f = time2str('%Y-%m-%d %X', $mtime);
open(my $fh, "-|", 'du', '-s', '--', "$dir/$_");
my $du = <$fh>;
($du) = split(' ',$du); # only want the first blank-separated field
close($fh).
printf "%s\t%s\t%s\n", $mtime_f, "$dir/$_" , $du;
}
closedir $dh;
};
有更简单、更短的方法可以做到这一点(使用 perl 或 awk 或其他语言),但这为报告有关目录及其内容的其他信息提供了有用的基础。perldoc -f stat
有关该函数可用信息的完整详细信息,请参阅stat()
。
顺便说一句,这可以在 中实现awk
,但您必须实现自己的stat()
函数和日期格式化函数。使用更方便perl
。
GNUawk
又名gawk
支持可加载模块,并且该filefuncs
模块提供了stat()
一个填充statdata[]
数组的模块。通过添加到脚本@load "filefuncs"
顶部来使用awk
。