【问题标题】:Update field in a specific column according to counts over previous records using awk根据使用 awk 对先前记录的计数更新特定列中的字段
【发布时间】:2020-07-02 09:41:21
【问题描述】:

我必须更新下面输入文件的第一个字段(不包括作为标题的前两行。BGL、GLC 和 LIN 之前的第一列中的数字是一个计数器,必须以这样的方式更新对于具有相同分子 BCL、GLC 和 LIN 的每一系列记录,计数器都会增加 1。

在我的输入文件的一小部分下方(我有 100 个类似的文件):

900 mgdg molecules in water t= 600000.00000 step= 400000000
177255
    1BGL     C5    1   2.709  14.491   1.493
    1BGL     H5    2   2.664  14.412   1.433
    1BGL     O5    3   2.717  14.464   1.627
    1BGL     C1    4   2.599  14.430   1.687
    1BGL     H1    5   2.546  14.350   1.634
    2GLC     O1   23   2.609  14.403   1.823
    2GLC     C1   24   2.675  14.276   1.837
    2GLC    H11   25   2.607  14.204   1.790
    3LIN     C3   44   3.033  14.281   2.268
    3LIN    H31   45   3.136  14.298   2.235
    4LIN     C3   87   3.108  13.927   2.066
    4LIN    H31   88   3.077  13.879   2.159
    1BGL     C5    1   2.709  14.491   1.493
    1BGL     H5    2   2.664  14.412   1.433
    1BGL     O5    3   2.717  14.464   1.627
    1BGL     C1    4   2.599  14.430   1.687
    1BGL     H1    5   2.546  14.350   1.634
    2GLC     O1   23   2.609  14.403   1.823
    2GLC     C1   24   2.675  14.276   1.837
    2GLC    H11   25   2.607  14.204   1.790
    3LIN     C3   44   3.033  14.281   2.268
    3LIN    H31   45   3.136  14.298   2.235
    4LIN     C3   87   3.108  13.927   2.066
    4LIN    H31   88   3.077  13.879   2.159
etc
    1BGL     C5    1   2.709  14.491   1.493
    1BGL     H5    2   2.664  14.412   1.433
    1BGL     O5    3   2.717  14.464   1.627
    1BGL     C1    4   2.599  14.430   1.687
    1BGL     H1    5   2.546  14.350   1.634
    2GLC     O1   23   2.609  14.403   1.823
    2GLC     C1   24   2.675  14.276   1.837
    2GLC    H11   25   2.607  14.204   1.790
    3LIN     C3   44   3.033  14.281   2.268
    3LIN    H31   45   3.136  14.298   2.235
    4LIN     C3   87   3.108  13.927   2.066
    4LIN    H31   88   3.077  13.879   2.159
etc
20389SOL     OW77253   0.644  14.144   5.376
20389SOL    HW177254   0.712  14.203   5.344
20389SOL    HW277255   0.577  14.201   5.413
   6.36535  23.37625  12.09434

我想作为输出:

900 mgdg molecules in water t= 600000.00000 step= 400000000
177255
    1BGL     C5    1   2.709  14.491   1.493
    1BGL     H5    2   2.664  14.412   1.433
    1BGL     O5    3   2.717  14.464   1.627
    1BGL     C1    4   2.599  14.430   1.687
    1BGL     H1    5   2.546  14.350   1.634
    1GLC     O1   23   2.609  14.403   1.823
    1GLC     C1   24   2.675  14.276   1.837
    1GLC    H11   25   2.607  14.204   1.790
    1LIN     C3   44   3.033  14.281   2.268
    1LIN    H31   45   3.136  14.298   2.235
    1LIN     C3   87   3.108  13.927   2.066
    1LIN    H31   88   3.077  13.879   2.159
    2BGL     C5    1   2.709  14.491   1.493
    2BGL     H5    2   2.664  14.412   1.433
    2BGL     O5    3   2.717  14.464   1.627
    2BGL     C1    4   2.599  14.430   1.687
    2BGL     H1    5   2.546  14.350   1.634
    2GLC     O1   23   2.609  14.403   1.823
    2GLC     C1   24   2.675  14.276   1.837
    2GLC    H11   25   2.607  14.204   1.790
    2LIN     C3   44   3.033  14.281   2.268
    2LIN    H31   45   3.136  14.298   2.235
    2LIN     C3   87   3.108  13.927   2.066
    2LIN    H31   88   3.077  13.879   2.159
etc
  900BGL     C5    1   2.709  14.491   1.493
  900BGL     H5    2   2.664  14.412   1.433
  900BGL     O5    3   2.717  14.464   1.627
  900BGL     C1    4   2.599  14.430   1.687
  900BGL     H1    5   2.546  14.350   1.634
  900GLC     O1   23   2.609  14.403   1.823
  900GLC     C1   24   2.675  14.276   1.837
  900GLC    H11   25   2.607  14.204   1.790
  900LIN     C3   44   3.033  14.281   2.268
  900LIN    H31   45   3.136  14.298   2.235
  900LIN     C3   87   3.108  13.927   2.066
  900LIN    H31   88   3.077  13.879   2.159
etc
20389SOL     OW77253   0.644  14.144   5.376
20389SOL    HW177254   0.712  14.203   5.344
20389SOL    HW277255   0.577  14.201   5.413
   6.36535  23.37625  12.09434

我主要使用这样的脚本,但这种情况更复杂,这个脚本没用。我知道我应该使用计数器,但是如果我有不同的名称(我的意思是 BGL、GLC、LIN)并且也很难使用它(FNR%22==0),因为我有 5 个 BGL 那么如何打印它3 GLC 然后 4 LIN。

#!/bin/bash
awk '
FNR==1{
  ++count
  value=count"BGL" (or whatever)
}
{
  $1=value
}
1
FNR%22==0{
  ++count
  value=count"BGL"
}
' after_SOL.gro | tee after_SOL2.gro

我也会对许多文件执行此操作,因此我将在 for 循环中 pyt 我的脚本:

#!/bin/bash
for num in {1..100}; 
do 
    (awk script here) eq4_$num.gro | tee eq5_$num.gro
done

【问题讨论】:

  • 你能用文字解释一下你的输入和输出有什么区别吗?
  • 是的,在我输入的第一列中:1BGL..2GLC..3LIN..4LIN..再一次是 1BGL..2GLC..3LIN..4LIN..再一次是 1BGL..2GLC ..3LIN..4LIN。在输出中我想要 1BGL..1GLC..1LIN 然后 2BGL..2GLC..2LIN 然后 3BGL..3GLC..3LIN 等
  • 你想sort?,你不需要 awk 来做到这一点......
  • 不,我不想排序。我想重命名每个原子中的第一列(每个原子都是一行)。在那种情况下排序是没用的,我有 900 个分子,所以我需要有 1 个 BGL/GLC/LIN、2 个 BG/GLC/LIN、3 个 BGL、GLC/LIN 4、5、6 个 BGL/GLC LIN 等。现在我到处都有 1BGL,到处都有 2 GLC,到处都有 3 LIN,到处都有 4 LIN。但你是对的。也许首先我应该排序所以我将有例如 10000 行 BGL,然后是 20000 行 GLC 和 50000 行 LIN,然后我将使用我粘贴在这里的脚本,所以我可以使用例如 if ( NR>=3 && NR
  • 你没有定义atom,但我猜它的'BGL'、'GLC'、LIN'等等。

标签: awk text-processing


【解决方案1】:

我相信这个脚本完全符合您的要求,并保留了输入的表格格式:

#!/bin/bash
awk '
NR <= 2 {print} /* skip two lines of headers */
NR > 2  {
  sub(/[0-9]*/, "", $1); 
  if ($1 != prev) {count[$1]++} 
  prev = $1
  printf ("%8s %6s %4s %7s %7s %7s\n", count[$1]$1, $2, $3, $4, $5, $6)
} ' data.txt

【讨论】:

    【解决方案2】:

    这个脚本应该重新编号分子。

    #!/usr/bin/gawk -f
    BEGIN{ mol=""; prev=""; }
    {
            gsub(/[0-9]/,"",$1);
            mol=$1;
            if (mol==prev){
                    nr=m[mol];
            }
            else {
                    nr=++m[mol]
            };
            prev=mol;
            print nr$0
    }
    

    每个分子 ('BGL','GLC',LIN') 的序列号都保存在数组 m[] 中。并随着分子的变化而增加。

    我希望这是计划在哪里做的?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2022-01-20
      相关资源
      最近更新 更多