所有这些答案都存储整个源文件.这是一个可怕的想法,将打破更大的文件.
这是一种只存储要输出的行数的快速方法(请注意,效率越高,tail总是会更快,因为它不会读取整个源文件!):
awk -vt=10 '{o[NR%t]=$0}END{i=(NR<t?0:NR);do print o[++i%t];while(i%t!=NR%t)}'
Run Code Online (Sandbox Code Playgroud)
更清晰(并且代码更少):
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)
}'
Run Code Online (Sandbox Code Playgroud)
清晰易读的代码说明:
这使用模运算符仅存储所需数量的项(tail变量).在解析每一行时,它存储在较旧的数组值之上(因此第11行存储在其中output[1]).
该END节将增量变量i设置为零(如果我们的行数少于所需的行数)或者行数,它告诉我们从何处开始调用保存的行.然后我们按顺序打印保存的行.当我们返回到第一个值(在我们打印之后)时,循环结束.
您可以替换if/ elsestanza(或我的高尔夫示例中的三元子句),i = NR如果您不关心获取空行来填充请求的数字(echo "foo" |awk -vt=10 …在"foo"行之前将有九个空行).
for(i=NR-num;i<=NR;i++)
print vect[$i]
Run Code Online (Sandbox Code Playgroud)
$表示位置参数.使用简单i:
for(i=NR-num;i<=NR;i++)
print vect[i]
Run Code Online (Sandbox Code Playgroud)
对我有用的完整代码是:
#!/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]
}
Run Code Online (Sandbox Code Playgroud)
您可能应该添加一些代码END来处理NR< num.
| 归档时间: |
|
| 查看次数: |
3284 次 |
| 最近记录: |