找到特定模式后,如何打印数据文件中的值,并在中间跳过一行?

找到特定模式后,如何打印数据文件中的值,并在中间跳过一行?

我有一个名为File-1.我必须匹配一个模式DATA_POINTS,然后在跳过一行后我想打印以下行的第六列。

  • File-1例子:
    here ! some other data exist but all of them are totally different from the below data!
    
    In simple words following data is completely unique.
    
    
    DATA_POINTS
    12
       0.0000000000     0.0000000000     0.0000000000  20   !  A
       0.5000000000     0.5000000000     0.0000000000  20   !  B
       0.7500000000     0.5000000000     0.2500000000  20   !  C
       0.7500000000     0.3750000000     0.3750000000  20   !  D
       0.0000000000     0.0000000000     0.0000000000  20   !  E
       0.5000000000     0.5000000000     0.5000000000  20   !  F
       0.6250000000     0.6250000000     0.2500000000  20   !  U
       0.7500000000     0.5000000000     0.2500000000  20   !  W
       0.5000000000     0.5000000000     0.5000000000  20   !  L
       0.7500000000     0.3750000000     0.3750000000  20   !  K
       0.6250000000     0.6250000000     0.2500000000  20   !  U
       0.5000000000     0.5000000000     0.0000000000  20   !  X
    
  • 所需输出
    S1 = A
    S2 = B
    S3 = C
    S4 = D
    S5 = E
    S6 = F
    S7 = U
    S8 = W
    S9 = L
    S10= K
    S11= U
    S12= X
    

该模式DATA_POINTS不会在文件中重复,并且需要精确匹配。

最近的解决方案

我从另一个 qsn 得到这个命令。如果第 6 列位于同一行模式中,则此方法有效

awk '/DATA_POINTS/{i==0 ; i++; getline; print "S"i"=", $6}' File-1

答案1

以下awk程序应该完成这项工作:

awk 'BEGIN{n=-1}
     n>0{printf "S%-*d=%s\n",w,++i,$6; if (i==n) {i=0;n=-1}}
     n==0{n=$1;w=length($1)}
     $0=="DATA_POINTS"{n=0}' file

这会:

  • 一开始n用初始化一个“状态标志” -1,意思是“在数据块之外”。
  • DATA_POINTS当遇到仅由字符串组成的行时,设置n0,意思是“下一行包含数据点数”
  • n为零时,该行的内容被解释为数据点的数量并存储在 中n。该数字的长度(以字符/数字为单位)存储在w用于稍后格式化输出的字段中。
  • n大于 时0,表明我们位于“数据”块内,使用计数变量i(使用格式设置为固定宽度w并按输出示例中的左侧调整)和该行的第 6 个字段打印“键”,i直到等于n,此时n重置为-1

这可能比您需要的功能更多,因为它可以处理不在文件末尾的数据块(它尊重标头中指定的数据行数,而不是只读取到文件末尾) )。

笔记目前查找的方法DATA_POINTS是全字符串匹配,如果实际字符串可以包含特殊字符,这是最稳健的方法。如果您想要部分字符串匹配或正则表达式匹配,请使用

index($0,"DATA_POINTS") { ... }

或(如您的示例所示)

/DATA_POINTS/ { ... }

此外,如果您想防止误解空行,请将n>0和分别替换n==0n>0&&NFn==0&&NF

答案2

$ awk '/DATA_POINTS/{c=3} c&&!--c{f=1} f{printf "S%d = %s\n", ++s, $6}' file
S1 = A
S2 = B
S3 = C
S4 = D
S5 = E
S6 = F
S7 = U
S8 = W
S9 = L
S10 = K
S11 = U
S12 = X

要从匹配行(含)的第 27 行而不是第 3 行开始打印,只需将 3 更改为 27。

https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105有关上述方法的更多信息以及赛后做某事的更多方法。

答案3

利用范围运算符,。开始是数据点行,结束是 eof。

awk '
 /DATA_POINTS/,0 {
    if ( /DATA_POINTS/ ) {
      getline; next 
   }
   printf "S%-2d=%s%s\n", ++k, OFS, $6
 }
' file

答案4

这是一个单行解决方案,使用 sed 提取行号,使用 bc 加 2,使用 tail 提取数据块,最后使用 awk 获取正确的列。可能不是最干净或最简单的解决方案,但对我来说,它比仅使用 awk 更清晰。

sed -n '/DATA_POINTS/=' $file | xargs -i echo '{}+2' | bc | xargs -i tail -n+{} $file | awk '{print $6}'

相关内容