【问题标题】:Implement tail with awk用 awk 实现 tail
【发布时间】:2012-02-24 10:56:57
【问题描述】:

我正在努力处理这个应该模拟 tail 命令的 awk 代码

num=$1;
{
    vect[NR]=$0;
    
}
END{
    for(i=NR-num;i<=NR;i++)
            print vect[$i]
}

所以我在这里想要实现的是一个由 awk/ 模拟的 tail 命令 例如考虑cat somefile | awk -f tail.awk 10 应该打印文本文件的最后 10 行,有什么建议吗?

【问题讨论】:

  • awk -f tail.awk num=10, 10 本身将被解释为文件名。祝你好运。
  • 你真的需要存储整个文件吗?
  • @Johnsyweb 好吧,不,但这是我想使用的方法,还有其他想法吗?随意发布它们:)
  • 既然你显然是在做这个练习,那么我发布的任何代码都对你没有帮助。
  • 这不是我今天在操作系统考试中遇到的问题,我只是想知道是否还有其他可行的替代方案

标签: linux bash scripting awk tail


【解决方案1】:
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]
}

您可能应该在END 中添加一些代码来处理NR num 时的情况。

【讨论】:

  • 当我尝试将文本文件放入 awk 时,我仍然在 ARGV[1] 上收到错误 ---------- ------------------------------------- 猫 test1.txt | awk -f tailawk 10
  • 请考虑我添加了一个 BEGIN{num=ARGV[1]}
【解决方案2】:

您需要在 awk 命令行中添加 -v num=10 以设置 num 的值。在你的最后一个循环中从NR-num+1 开始,否则你会得到num+1 的输出行。

【讨论】:

  • 是的,谢谢,我忘记增加 nr-num,因为我尝试从 nr 向后读取到 nr-num 并交换索引并忘记增加,谢谢
【解决方案3】:

这可能对你有用:

awk '{a=a b $0;b=RS;if(NR<=v)next;a=substr(a,index(a,RS)+1)}END{print a}' v=10

【讨论】:

  • 如果有解释,我会赞成。我能理解,但需要给大家解释一下。
【解决方案4】:

所有这些答案都存储了整个源文件。这是一个可怕的想法,并且会破坏更大的文件。

这是一种只存储要输出的行数的快速方法(请注意,更高效的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”的行之前会有九个空行)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多