You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查找模式最后一次出现位置并打印其前20行

解决方案:获取模式最后一次出现位置的前20行及模式本身

最优单Awk命令(兼容所有POSIX环境)

直接用一条Awk命令就能完成需求,无需多进程调用,效率更高且兼容性拉满:

awk '/====/ {pos=NR} END {start=(pos<20?1:pos-20); for(i=start;i<=pos;i++) print lines[i]} {lines[NR]=$0}' inputfile

命令逻辑说明:

  1. 遍历文件时,每匹配到====模式,就更新pos变量为当前行号(最终pos就是模式最后一次出现的行号)
  2. 同时把每一行内容存入数组lines,用行号NR作为索引
  3. 到文件结尾的END块时:
    • 计算起始行号start:如果最后匹配行的行号小于20,就从第1行开始;否则从pos-20开始
    • 循环打印从start到pos的所有行,包含模式行本身,且不会打印模式后的内容

对比原有脚本的优势

你原来的分步骤脚本虽然能运行,但存在以下问题:

  • 需要启动awk+expr+awk三个进程,处理大文件(比如2万行)时效率更低
  • 没有处理holdline<20的边界情况(此时befholdline会是负数,虽Awk会自动忽略负数的NR判断,但逻辑不够严谨)
  • 代码冗余,不如单条Awk命令简洁

补充:改进版Sed方案(仅作参考)

如果一定要用Sed,也可以实现,但逻辑相对复杂,且依赖Sed的保持空间操作,不如Awk直观:

sed -n '
/====/ {
    # 匹配到模式时,清空保持空间,存入当前行及之前19行
    H
    s/\n//g
    h
    n
    b
}
# 非模式行,将当前行追加到保持空间,然后只保留最后20行
H
s/.*\(\n.*\)\{20\}/\1/
h
$ {
    # 最后一行时,取出保持空间并打印
    x
    p
}
' inputfile

不过这个Sed方案对换行符的处理需要注意,且部分极简版Sed可能不支持大括号语法,还是推荐Awk方案。

内容的提问来源于stack exchange,提问作者Aires69

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:55:15