只有在给定模式匹配时才使用sed或awk获取范围

时间:2017-09-23 07:14:50

标签: shell awk sed

输入:

START
OS:: UNIX
Release: xxx
Version: xxx
END
Description about UNIX
  <Multiline>
START
OS:: LINUX
Release: xxx
Version: xxx
END
Description about LINUX
  <Multiline>
START
OS:: Windows
Release: xxx
Version: xxx
END
Description about Windows
  <Multiline>

这里我试图获取START和END之间的所有信息,只有我能匹配操作系统类型。

我可以获取START和END之间的所有数据,但是我不知道如何匹配模式

使用SED

sed -n '/START/,/END/p'

使用AWK

awk '/START/,/END/'

预期输出

搜索Linux时

START
OS:: LINUX
Release: xxx
Version: xxx
END

需要帮助!!

先谢谢

4 个答案:

答案 0 :(得分:0)

$ awk 'last~/START/ && /LINUX/ {print last; f=1} f{print} /END/{f=0} {last=$0}' file
START
OS:: LINUX
Release: xxx
Version: xxx
END

即使输入中的行位于START-END块之外,此方法也能正常工作。

如何运作

  • last~/START/ && /LINUX/ {print last; f=1}

    如果最后一行与START匹配且当前行与LINUX匹配,则打印最后一行并将变量f设置为1.

  • f{print}

    如果f非零,请打印当前行。

  • /END/{f=0}

    如果当前行与END匹配,则将f设置为零。

  • last=$0

    将当前行保存在变量last

答案 1 :(得分:0)

$ awk 'BEGIN{RS=ORS="END\n"}/LINUX/' file
START
OS:: LINUX
Release: xxx
Version: xxx
END

它将输入和输出记录分隔符设置为END\n,因此每条记录基本上有一个START-END块(技术上START-而不是END,因为它是记录分隔符),并打印出其中包含LINUX的块。修改匹配的正则表达式部分(/LINUX/)以满足您的需求。

答案 2 :(得分:0)

你能不能尝试关注awk,如果有帮助请告诉我。

awk '/START/{count++} /OS.*LINUX/ && count{count++} /END/ && count==2{print val RS $0;val=count="";next}{val=val?val ORS $0:$0}/END/{count=val=""}'  Input_file

也添加非单线形式的解决方案。

awk '
/START/{
  count++
}
/OS.*LINUX/ && count{
  count++
}
/END/ && count==2{
  print val RS $0;
  val=count="";
  next
}
{
  val=val?val ORS $0:$0
}
/END/{
  count=val=""
}
'  Input_file

输出如下。

START
OS:: LINUX
Release: xxx
Version: xxx
END

答案 3 :(得分:0)

awk 解决方案:

awk '/START/{pr=$0}/LINUX/{ print pr; n=NR+3 }NR<=n{print}' file

输出:

START
OS:: LINUX
Release: xxx
Version: xxx
END