【问题标题】:Print lines in between two patterns using awk or sed使用 awk 或 sed 在两个模式之间打印行
【发布时间】:2017-11-05 16:04:00
【问题描述】:

我想解析文件的输出,首先 grep 找到两个模式的行以唯一字符串开头(即 ATOM,!),然后在这个 grep 行中找到另一个模式(PVAL,PLMS)并打印。例如

ATOM 17 COMMENT CL01 
 PRNT 16 
 PVAL    7.243  SIGPV    0.038 
 PLMS 1  1  -0.034   PLMS 3  1  -0.050 
 PLMS 3  3  -0.063   PLMS 4  4   0.016
! 
ATOM 17 COMMENT CL02
 NIEG 2
 PVAL    7.242  SIGPV    0.008 
 PLMS 1  1  -0.046   PLMS 3  1  -0.011 
 PLMS 3  3   0.072   PLMS 4  4   0.019 
!
ATOM 9 COMMENT F01
 NEIG 4 
 EXCEPT OH 
 PVAL    7.185   SIGPV    0.031
 PLMS 1  1  -0.064   PLMS 2 -2   0.005
 PLMS 3  1  -0.011   PLMS 4  2  -0.006
 PLMS 4  4   0.006
!

预期的 o/p 应该是

ATOM 17 COMMENT CL01 PVAL    7.243  SIGPV    0.038 PLMS 1  1  -0.034   PLMS 3  1  -0.050 PLMS 3  3  -0.063   PLMS 4  4   0.016

ATOM 17 COMMENT CL02  PVAL    7.242  SIGPV    0.008 PLMS 1  1  -0.046   PLMS 3  1  -0.011 PLMS 3  3   0.072   PLMS 4  4   0.019

ATOM 9 COMMENT F01 PVAL    7.185   SIGPV    0.031 PLMS 1  1  -0.064   PLMS 2 -2   0.005 PLMS 3  1  -0.011   PLMS 4  2  -0.006 PLMS 4  4   0.006

非常感谢任何建议。

【问题讨论】:

    标签: bash shell awk sed


    【解决方案1】:

    如果您的真实输入文件与您发布的相同,即使低于一个也可以提供所需的输出。

    # either
    awk  'f=/ATOM|PVAL|PLMS|!/{ORS=/^!/?RS:OFS; if(/^!/)$1=""}f' infile
    
    # or
    awk  'f=/ATOM|PVAL|PLMS/{ORS=OFS}!f && f=/!/{ORS=RS; $1=""}f' infile
    

    输入:

    $ cat infile
    ATOM 17 COMMENT CL01 
     PRNT 16 
     PVAL    7.243  SIGPV    0.038 
     PLMS 1  1  -0.034   PLMS 3  1  -0.050 
     PLMS 3  3  -0.063   PLMS 4  4   0.016
    ! 
    ATOM 17 COMMENT CL02
     NIEG 2
     PVAL    7.242  SIGPV    0.008 
     PLMS 1  1  -0.046   PLMS 3  1  -0.011 
     PLMS 3  3   0.072   PLMS 4  4   0.019 
    !
    ATOM 9 COMMENT F01
     NEIG 4 
     EXCEPT OH 
     PVAL    7.185   SIGPV    0.031
     PLMS 1  1  -0.064   PLMS 2 -2   0.005
     PLMS 3  1  -0.011   PLMS 4  2  -0.006
     PLMS 4  4   0.006
    !
    

    输出 1:

    $ awk  'f=/ATOM|PVAL|PLMS|!/{ORS=/^!/?RS:OFS; if(/^!/)$1=""}f' infile
    ATOM 17 COMMENT CL01   PVAL    7.243  SIGPV    0.038   PLMS 1  1  -0.034   PLMS 3  1  -0.050   PLMS 3  3  -0.063   PLMS 4  4   0.016 
    ATOM 17 COMMENT CL02  PVAL    7.242  SIGPV    0.008   PLMS 1  1  -0.046   PLMS 3  1  -0.011   PLMS 3  3   0.072   PLMS 4  4   0.019  
    ATOM 9 COMMENT F01  PVAL    7.185   SIGPV    0.031  PLMS 1  1  -0.064   PLMS 2 -2   0.005  PLMS 3  1  -0.011   PLMS 4  2  -0.006  PLMS 4  4   0.006 
    

    输出 2:

    $ awk  'f=/ATOM|PVAL|PLMS/{ORS=OFS}!f && f=/!/{ORS=RS; $1=""}f' infile
    ATOM 17 COMMENT CL01   PVAL    7.243  SIGPV    0.038   PLMS 1  1  -0.034   PLMS 3  1  -0.050   PLMS 3  3  -0.063   PLMS 4  4   0.016  
    ATOM 17 COMMENT CL02  PVAL    7.242  SIGPV    0.008   PLMS 1  1  -0.046   PLMS 3  1  -0.011   PLMS 3  3   0.072   PLMS 4  4   0.019  
    ATOM 9 COMMENT F01  PVAL    7.185   SIGPV    0.031  PLMS 1  1  -0.064   PLMS 2 -2   0.005  PLMS 3  1  -0.011   PLMS 4  2  -0.006  PLMS 4  4   0.006 
    

    【讨论】:

      【解决方案2】:

      awk解决方案:

      awk '/^ATOM/{ f=1; r=$0 }/^!/{ print r; f=0 }f && ($1~/^(PVAL|PLMS)/){ r=r OFS $0 }' file
      

      输出:

      ATOM 17 COMMENT CL01   PVAL    7.243  SIGPV    0.038   PLMS 1  1  -0.034   PLMS 3  1  -0.050   PLMS 3  3  -0.063   PLMS 4  4   0.016
      ATOM 17 COMMENT CL02  PVAL    7.242  SIGPV    0.008   PLMS 1  1  -0.046   PLMS 3  1  -0.011   PLMS 3  3   0.072   PLMS 4  4   0.019 
      ATOM 9 COMMENT F01  PVAL    7.185   SIGPV    0.031  PLMS 1  1  -0.064   PLMS 2 -2   0.005  PLMS 3  1  -0.011   PLMS 4  2  -0.006  PLMS 4  4   0.006
      

      【讨论】: