【问题标题】:awk extract lines between two patterns with a twistawk 提取两个模式之间的线条
【发布时间】:2023-01-13 09:14:03
【问题描述】:

我有一种数据文件只包含一次(!)以下文本块:

Begin final coordinates
     new unit-cell volume =    460.57251 a.u.^3 (    68.24980 Ang^3 )
     density =      7.37364 g/cm^3

CELL_PARAMETERS (alat=  7.29434300)
   0.995319813   0.000000000   0.000000000
   0.000000000   0.995319813   0.000000000
   0.000000000   0.000000000   1.197882354

ATOMIC_POSITIONS (crystal)
Pb            0.0000000000        0.0000000000       -0.0166356359
O             0.5000000000        0.5000000000        0.1549702780
Ti            0.5000000000        0.5000000000        0.5327649171
O             0.0000000000        0.5000000000        0.6381882204
O             0.5000000000        0.0000000000        0.6381882204
End final coordinates

我已经找到了如何提取 Begin final coordinatesEnd final coordinates 模式之间的整个行块,但我需要对其进行更完善。我想首先提取以CELL_PARAMETERS 开头的行下方的三行。然后我想提取(使用不在同一个 awk 命令中的另一个动作)ATOMIC_POSITIONS 下面的 5 行。

我必须在这里做一个观察:我在开始时说过文本块只出现一次,对于 Begin final coordinatesEnd final coordinates 的特定形式也是如此。在整个数据文件中,有许多具有这种形式的块:

CELL_PARAMETERS (alat=  7.29434300)
   0.995319813   0.000000000   0.000000000
   0.000000000   0.995319813   0.000000000
   0.000000000   0.000000000   1.197882354

ATOMIC_POSITIONS (crystal)
Pb            0.0000000000        0.0000000000       -0.0166356359
O             0.5000000000        0.5000000000        0.1549702780
Ti            0.5000000000        0.5000000000        0.5327649171
O             0.0000000000        0.5000000000        0.6381882204
O             0.5000000000        0.0000000000        0.6381882204

所以不幸的是,我不能只使用 CELL_PARAMETERSATOMIC_POSITIONS 行作为模式。唯一只出现一次的是 Begin final coordinatesEnd final coordinates 所以我必须提取与这些行相关的文本。

我试图将从 here 中提取两种模式之间的线的方法与从 here 中找到模式后跳过 N 行的方法结合起来。不幸的是我不能让它工作。

所以我的想法是:

  1. 对于第一种情况:我试图找到 Begin final coordinates 模式并跳过 5 行,包括带有模式的那一行)然后打印我感兴趣的 3 行,然后跳过其余行直到 End final coordinates

  2. 对于第二种情况:找到Begin final coordinates 然后跳过行直到 ATOMIC_POSITIONS(也跳过这一行),打印接下来的 5 行直到 End final coordinates

    这可以做到吗?

    更新:

    我刚刚试过这个:

    awk '/Begin final coordinates/ {n=NR+9} n < NR < n+3'
    

    但我收到语法错误:

    awk: cmd. line:1: /Begin final coordinates/ {n=NR+9} n<NR<n+3
    awk: cmd. line:1:                                        ^ syntax error
    

    我在这里做错了什么?

    更新2:

    按住压力机,我明白了!

    1. 这解决了第一个案例:awk '/Begin final coordinates/{n=NR+4;m=NR+8} (n&lt;NR) &amp;&amp; (NR&lt;m)' file
    2. 这解决了第二种情况:awk '/Begin final coordinates/{n=NR+9;m=NR+8} (n&lt;NR) &amp;&amp; (NR&lt;m)' file

      不是很好,但它会完成这项工作!

【问题讨论】:

    标签: awk


    【解决方案1】:

    按住压力机,我明白了!

    1. 这解决了第一种情况:

      awk '/Begin final coordinates/{n=NR+4;m=NR+8} (n<NR) && (NR<m)' file
      
    2. 这解决了第二种情况:

      awk '/Begin final coordinates/{n=NR+9;m=NR+8} (n<NR) && (NR<m)' file
      

    【讨论】:

      【解决方案2】:

      有了这个,您只需要读取一次输入:

      awk '/Begin final coordinates/{n1=NR+4;m1=NR+8; n2=NR+9;m2=NR+8} 
           (n1<NR) && (NR<m1){ print > "CELL_PARAMETERS.txt"; }
           (n2<NR) && (NR<m2){ print > "ATOMIC_POSITIONS.txt"; }
           ' file
      

      【讨论】:

        【解决方案3】:

        假设 Begin final 块仅出现在所有其他块之后:

        $ awk '/^Begin final/{f=1} c&&c--; f && /^CELL/{c=3}' file
           0.995319813   0.000000000   0.000000000
           0.000000000   0.995319813   0.000000000
           0.000000000   0.000000000   1.197882354
        
        $ awk '/^Begin final/{f=1} c&&c--; f && /^ATOMIC/{c=5}' file
        Pb            0.0000000000        0.0000000000       -0.0166356359
        O             0.5000000000        0.5000000000        0.1549702780
        Ti            0.5000000000        0.5000000000        0.5327649171
        O             0.0000000000        0.5000000000        0.6381882204
        O             0.5000000000        0.0000000000        0.6381882204
        

        或者如果它可能出现在任何地方,则将 c&amp;&amp;c--; 更改为 c{print; if (!c--) exit}

        相关成语见https://stackoverflow.com/a/17914105/1745001

        【讨论】:

          猜你喜欢
          • 2019-09-28
          • 1970-01-01
          • 2018-06-08
          • 1970-01-01
          • 1970-01-01
          • 2013-08-21
          • 2016-12-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多