繁体   English   中英

在找到第一个图案sed的基础上,找到图案并打印行awk grep

[英]find a pattern and print line based on finding the first pattern sed, awk grep

我的档案很大。 通用的是打破每个部分示例的主机名:

HOSTNAME:host1
   data 1
     data here
   data 2 
      text here
   section 1
      text here
   part 4  
      data here
   comm = 2

HOSTNAME:host-2

   data 1
     data here
   data 2 
      text here
   section 1
      text here
   part 4  
      data here
   comm = 1

以上打印

如您在上方看到的,在每个部分之间,还有其他部分按具有特定值的关键字或行细分

我喜欢使用oneliner为每个部分打印主机名,然后在每个主机名部分下打印我要提取的行

你能帮忙吗? 我现在正在使用grep -C 10 HOSTNAME | gerp -C模式,但这假设每个部分中有10行。 这不是执行此操作的最佳方法。 有人可以显示更好的方法吗? 我还需要能够在找到的每种模式下打印多行。 因此,如果我找到data1并且它下面还有其他行,我想抓取并打印它们

所以命令的输出就像

grep -C 10 HOSTNAME | grep data 1  
grep -C 10 HOSTNAME | grep -A 2 data 1 

HOSTNAME:Host1

   data 1  

HOSTNAME:Hoss2

   data 1 

在Grep旁边,我使用此sed命令来打印我的输出

sed -r '/HOSTNAME|shared/!d' filename

这个sed命令的唯一问题是,它仅打印其中包含共享模式和HOSTNAME的行。 我还需要在与共享模式匹配的行下指定我要打印的行数。 因此,我喜欢打印HOSTNAME,并在共享的第二个搜索模式下给出我希望打印的行数。

谢谢

这是一个sed twoliner:

sed -n -r '/HOSTNAME/ { p }                                  
          /^\s+data 1/ {p }' hostnames.txt 

打印( p

  • 当该行包含HOSTNAME时
  • 当该行以某些空白( \\s+ )开头,后跟您的搜索条件( data 1
  • 不打印非数学行(由于sed -n选项)

编辑:一些备注:

  • 这已经在Linux下用GNU sed 4.2.2进行了测试
  • 如果您的sed版本不支持-r ,则将第二个模式替换为/^.*data 1/
  • 我们可以将所有东西压扁;

综上所述,这里是一行的修订版本,不需要扩展的正则表达式(即,没有-r ):

sed -n '/HOSTNAME/ { p } ; /^.*data 1/ {p }' hostnames.txt

awk来救援!

$ awk -v lines=2 '/HOSTNAME/{c=lines} NF&&c&&c--' file

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

打印lines包括模式匹配在内的lines数,跳过空行。

如果要指定辅助关键字而不是行数

$ awk -v key='data 1' '/HOSTNAME/{h=1; print} h&&$0~key{print; h=0}' file

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

OP的要求似乎还不清楚,但是以下内容与对要求的一种解释是一致的,更重要的是,该程序没有特殊要求,并且可以轻松地修改代码以满足各种要求。 特别是,两个搜索模式(HOSTNAME模式和“数据1”模式)都可以轻松地进行参数化。

主要思想是打印指定小节中的所有行,或至少打印一定数量的行,直至达到某个限制。

如果在子节中应打印的行数上有限制,请为限制指定一个值,否则将其设置为0。

awk -v limit=0 '
  /^HOSTNAME:/ { subheader=0; hostname=1; print; next}
  /^ *data 1/  { subheader=1; print; next }
  /^ *data /   { subheader=0; next }          
  subheader && (limit==0 || (subheader++ < limit)) { print }'

给定问题中提供的行,输出将是:

HOSTNAME:host1
   data 1
HOSTNAME:host-2
   data 1

(是的,我知道awk程序中的变量“主机名”当前尚未使用,但我将其包括在内以使其易于添加测试,从而满足有关识别子标题的前提条件的某些显而易见的要求。)

sed -n -e'/主机名/,+ p'-e'/双工/,+ p'最简单的方法是组合两个sed命令..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM