两种模式之间的Grep线,一种独特且一种重复

问题描述

我有一个看起来像这样的文本文件

    1
    bbbbb
    aaa
    END
    2
    ttttt
    mmmm
    uu
    END
    3
    ....
    END

单个数字模式(1,2,3)和END之间的行数是可变的。因此上限定界模式会发生变化,但最后一个定界模式不会发生变化。使用一些bash命令,我想在指定的上一个伙伴和对应的END之间grep行,例如,一个将输入2作为输入并返回

的命令。
    2
    ttttt
    mmmm
    uu
    END

我已经用sed和awk尝试了各种解决方案,但仍然无法解决。主要问题是我可能需要在文件中间添加一个条目,因此我不能将sed与/ pattern / q一起使用...任何帮助将不胜感激!

解决方法

使用awk,我们在匹配作为输入参数的开始模式时设置了一个标志f。在该行之后,该标志将打开,并打印每一行。当到达“ END”(并且该标志处于打开状态!)时,它退出。

awk -v p=2 '$0~p{f=1} f{print} f&&/END/{exit}' file
,

使用sed及其地址仅在模式之间打印文件的一部分:

#!/bin/bash
start=x
while [[ $start = *[^0-9]* ]] ; do
    read -p 'Enter the start pattern: ' start
done
sed -n "/^$start$/,/^END$/p" file
,

您可以将sed与地址范围一起使用。为方便起见,修改RE1中的第一个正则表达式(/RE1/,/RE2/):

sed -n '/^[[:space:]]*2$/,/^[[:space:]]*END$/p' file

或者,

sed '
    /^[[:space:]]*2$/,/^[[:space:]]*END$/!d
    /^[[:space:]]*END$/q
' file

这会在读取END后退出,因此可能更有效。

,

仅使用bash

的另一个选项/解决方案
#!/usr/bin/env bash

start=$1

while IFS= read -r lines; do
  if [[ ${lines##* } == $start ]]; then
    print=on
  elif [[ ${lines##* } == [0-9] ]]; then
    print=off
  fi
  case $print in on) printf '%s\n' "$lines";; esac
done < file.txt

以数字作为参数运行脚本,1可以2或3或...

./myscript 1
,

这可能对您有用(GNU sed):

sed -n '/^\s*2$/{:a;N;/^\s*END$/M!ba;p;q}' file

通过设置-n选项关闭隐式打印。

聚集以2开头的行和以END开头的行的行,打印集合并退出。

第二个正则表达式使用M标志,当多行被匹配时,它允许^$匹配行的开始和结束。要记住的另一件事是,使用范围sed -n '/start/,/end/p' file将在满足第一个条件时开始打印行,如果第二个匹配不成立,它将继续打印到文件末尾。 / p>

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...