如何在Linux Shell中删除匹配行及其前后各一行的内容
解决方案
这里提供两种常用实现方式,你可以根据使用场景选择:
方案1:sed单行命令
如果是GNU sed(Linux系统默认自带),可以直接用以下命令修改原文件:
sed -i '/NaN/{x;s/^/del/;x;N;d};x;/del/{s/.*//;x;d};x' file.txt
命令逻辑说明:
- 匹配到含
NaN的行时,先标记上一行需要删除,再读入后一行和当前行一起删除,同时覆盖标记避免重复计算 - 处理新行前先检查上一轮标记,如果有删除标记就直接丢弃当前行,自动清理匹配行的前一行
如果是macOS系统自带的sed,-i参数需要额外加空后缀,写法调整为:
sed -i '' '/NaN/{x;s/^/del/;x;N;d};x;/del/{s/.*//;x;d};x' file.txt
方案2:awk命令(兼容性更好,逻辑更易调试)
awk写法对多连续匹配的场景容错性更高,不会出现漏删/多删问题,跨Linux、macOS都可以直接用:
awk '{ if (skip_next == 1) { skip_next = 0; next } if (/NaN/) { prev = ""; skip_next = 1; next } if (prev != "") print prev prev = $0 } END { if (prev != "") print prev }' file.txt > tmp_file && mv tmp_file file.txt
命令逻辑说明:
- 用
prev变量暂存上一行内容,skip_next标记当前匹配行的后一行是否需要删除 - 匹配到
NaN时直接清空上一行缓存(实现删除前一行),设置标记跳过下一行,同时不保留当前行 - 遍历结束后输出最后一行的缓存内容,避免丢失末尾正常行
内容的提问来源于stack exchange,提问作者Winston Pan
相关产品推荐
相关产品推荐

