首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用awk实现tail

使用awk实现tail
EN

Stack Overflow用户
提问于 2012-02-02 02:36:26
回答 4查看 4.3K关注 0票数 4

我正在努力使用这段awk代码,它应该模拟tail命令

代码语言:javascript
复制
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行,有什么建议吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-02 02:40:46

代码语言:javascript
复制
for(i=NR-num;i<=NR;i++)
    print vect[$i]

$表示位置参数。只使用普通的i

代码语言:javascript
复制
for(i=NR-num;i<=NR;i++)
    print vect[i]

对我有效的完整代码是:

代码语言:javascript
复制
#!/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添加一些代码来处理这种情况。

票数 5
EN

Stack Overflow用户

发布于 2015-10-14 03:13:16

所有这些答案都存储了整个源文件。这是一个可怕的想法,并且会在较大的文件上崩溃。

这里有一个只存储要输出的行数的快速方法(请注意,效率越高的tail总是越快,因为它不会读取整个源文件!):

代码语言:javascript
复制
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更少):

代码语言:javascript
复制
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

票数 7
EN

Stack Overflow用户

发布于 2012-02-02 02:50:07

您需要在awk命令行中添加-v num=10来设置num的值。在最后一次循环中从NR-num+1开始,否则将以num+1输出行结束。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9101296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档