用awk实现tail

问题描述 投票:0回答:5

我正在努力处理这个应该模拟 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 行,有什么建议吗?

linux bash scripting awk tail
5个回答
9
投票

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

这是一种仅存储要输出的行数的快速方法(请注意,更高效的

tail
总是会更快,因为它不会读取整个源文件!):

awk -vt=10 '{o[NR%t]=$0}END{i=(NR<t?0:NR);do print o[++i%t];while(i%t!=NR%t)}'

更清晰(并且更少的代码高尔夫):

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)
  }'

清晰代码说明:

这使用 取模运算符 仅存储所需数量的项目(

tail
变量)。解析每一行时,它都存储在旧数组值的顶部(因此第 11 行存储在
output[1]
中)。

END
节将增量变量
i
设置为零(如果我们的行数少于所需的行数)或行数,这告诉我们从哪里开始调用已保存的行。然后我们按顺序打印保存的行。当我们返回到第一个值时(在打印它之后),循环结束。

如果您不关心用空行来填充请求的数字(

if
将在“foo”行之前有九个空行)。
    
else

i = NR
表示位置参数。使用普通的

echo "foo" |awk -vt=10 …

5
投票
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] }
 时的情况。

您需要在 awk 命令行中添加 
END
来设置 <
NR
的值。并在最后一个循环中从

num

2
投票
-v num=10

行输出。

    
这可能对你有用:

num
    


2
投票
NR-num+1

确实取决于两种完全不同的场景:


0
投票
num+1

方法。


    虽然是一个固定文件(或任何“可查找”的虚拟设备),特别是如果文件很大并且您要查找的 # 行内容很大,那么预先快速进行
  1. awk '{a=a b $0;b=RS;if(NR<=v)next;a=substr(a,index(a,RS)+1)}END{print a}' v=10

    操作是值得的,跳过所有临时数组存储:

    
    

  2. tail

    arr[ NR % tail_n ]

wc -l
根据文件的总大小与行数比率,
( time ( mawk2 -v ___='3.14159 %' 'BEGIN { index(__ = ARGV[ARGC-!_],_ = "\47") && gsub(_,(_ "\\" _)_, __) (_ = "LC_ALL=C gwc -l "(_ __)_) | getline close(_) printf("\f\f\t %d...\f\f\n", ___ = int(((_ = 100) - ___) * $1 /_)) >>("/dev/stderr") FS = RS } ___ < NR' "$f" ) | pv ) | xxh128sum | gcat -b ; sleep 4; ( time ( LC_ALL=C gtail -n 4654474 "$f" ) | pv ) | xxh128sum | gcat -b out9: 1.39GiB 0:00:07 [ 193MiB/s] [ 193MiB/s] [ <=> ]
的速度为
 ( mawk2 -v ___='3.14159 %' "$f" )  

 5.49s user 1.86s system 99% cpu 7.370 total

 1  607efeee007a7e50cc06ce287a82e78f  stdin
的 1.0x-2.5x,特别适用于固定文件而不是管道。

© www.soinside.com 2019 - 2024. All rights reserved.