我正在努力使用这段awk代码,它应该模拟tail命令
num=$1;
{
vect[NR]=$0;
}
END{
for(i=NR-num;i<=NR;i++)
print vect[$i]
}因此,我在这里尝试实现的是一个由awk/模拟的尾部命令,例如考虑cat somefile | awk -f tail.awk 10应该打印文本文件的最后10行,有什么建议吗?
发布于 2012-02-02 02:40:46
for(i=NR-num;i<=NR;i++)
print vect[$i]$表示位置参数。只使用普通的i
for(i=NR-num;i<=NR;i++)
print vect[i]对我有效的完整代码是:
#!/usr/bin/awk -f
BEGIN{
num=ARGV[1];
# Make that arg empty so awk doesn't interpret it as a file name.
ARGV[1] = "";
}
{
vect[NR]=$0;
}
END{
for(i=NR-num;i<=NR;i++)
print vect[i]
}当NR < num时,您可能应该向END添加一些代码来处理这种情况。
发布于 2015-10-14 03:13:16
所有这些答案都存储了整个源文件。这是一个可怕的想法,并且会在较大的文件上崩溃。
这里有一个只存储要输出的行数的快速方法(请注意,效率越高的tail总是越快,因为它不会读取整个源文件!):
awk -vt=10 '{o[NR%t]=$0}END{i=(NR<t?0:NR);do print o[++i%t];while(i%t!=NR%t)}'更易读(code golf更少):
awk -v tail=10 '
{
output[NR % tail] = $0
}
END {
if(NR < tail) {
i = 0
} else {
i = NR
}
do {
i = (i + 1) % tail;
print output[i]
} while (i != NR % tail)
}'易读代码说明:
它使用modulo operator仅存储所需数量的项目( tail变量)。在解析每一行时,它被存储在较旧的数组值之上(因此,第11行存储在output[1]中)。
END节将增量变量i设置为零(如果行数少于所需的行数),否则设置为行数,这告诉我们从哪里开始调用保存的行。然后,我们按顺序打印保存的行。当我们返回到第一个值(在我们打印它之后)时,循环结束。
如果您不关心让空行填充所请求的数字(echo "foo" |awk -vt=10 …将在带有“foo”的行之前有9个空行),则可以将if/foo节(或我的golfed示例中的ternary clause )仅替换为i = NR。
发布于 2012-02-02 02:50:07
您需要在awk命令行中添加-v num=10来设置num的值。在最后一次循环中从NR-num+1开始,否则将以num+1输出行结束。
https://stackoverflow.com/questions/9101296
复制相似问题