【问题标题】:Move a line matching a specific pattern to another line matching a different pattern using sed使用 sed 将匹配特定模式的行移动到匹配不同模式的另一行
【发布时间】:2014-08-19 19:04:26
【问题描述】:

我是 sed 和 awk 的初学者,但我可以完成基本任务。我的工作存在问题,涉及将文件中的某些行从一个位置重新排列到另一个位置。

在以下示例中,我想捕获包含模式“O”(带有空格)的行,并将其移动到包含模式“N”的行之前:

    ATOM   1771  C   ALA A  61      48.797 
    ATOM   1772  O   ALA A  61      49.998 
    ATOM   1773  CB  ALA A  61      48.018 
    ATOM   1774  HB1 ALA A  61      48.964 
    ATOM   1775  HB2 ALA A  61      47.476 
    ATOM   1776  HB3 ALA A  61      47.420 
    ATOM   1777  N   LYS A  62      47.854 
    ATOM   1778  H   LYS A  62      46.979 
    ATOM   1779  CA  LYS A  62      48.163 
    ATOM   1780  HA  LYS A  62      49.236 
    ATOM   1781  C   LYS A  62      47.633 
    ATOM   1782  O   LYS A  62      47.789 
    ATOM   1783  CB  LYS A  62      47.541 
    ATOM   1784  HB2 LYS A  62      47.693 
    ATOM   1785  HB3 LYS A  62      46.473 
    ATOM   1798  HZ3 LYS A  62      45.853 
    ATOM   1799  N   GLY A  63      47.001 
    ATOM   1800  H   GLY A  63      46.906 

变成:

    ATOM   1771  C   ALA A  61      48.797 
    ATOM   1773  CB  ALA A  61      48.018 
    ATOM   1774  HB1 ALA A  61      48.964 
    ATOM   1775  HB2 ALA A  61      47.476 
    ATOM   1776  HB3 ALA A  61      47.420 
    ATOM   1772  O   ALA A  61      49.998 
    ATOM   1777  N   LYS A  62      47.854 
    ATOM   1778  H   LYS A  62      46.979 
    ATOM   1779  CA  LYS A  62      48.163 
    ATOM   1780  HA  LYS A  62      49.236 
    ATOM   1781  C   LYS A  62      47.633 
    ATOM   1783  CB  LYS A  62      47.541 
    ATOM   1784  HB2 LYS A  62      47.693 
    ATOM   1785  HB3 LYS A  62      46.473 
    ATOM   1798  HZ3 LYS A  62      45.853 
    ATOM   1782  O   LYS A  62      47.789 
    ATOM   1799  N   GLY A  63      47.001 
    ATOM   1800  H   GLY A  63      46.906 

有什么建议吗?非常感谢您的宝贵时间!

【问题讨论】:

    标签: regex perl bash sed pattern-matching


    【解决方案1】:

    这可能对你有用(GNU sed):

    sed '/\sO\s/{h;d};/\sN\s/{H;x}' file
    

    O 行保存在保留空间中,然后将其删除,将N 行附加到它并同时打印出来。

    【讨论】:

      【解决方案2】:

      另一个awk

      awk '$3=="O" {f=$0;next} $3=="N" {$0=f RS$0}1'
          ATOM   1771  C   ALA A  61      48.797
          ATOM   1773  CB  ALA A  61      48.018
          ATOM   1774  HB1 ALA A  61      48.964
          ATOM   1775  HB2 ALA A  61      47.476
          ATOM   1776  HB3 ALA A  61      47.420
          ATOM   1772  O   ALA A  61      49.998
          ATOM   1777  N   LYS A  62      47.854
          ATOM   1778  H   LYS A  62      46.979
          ATOM   1779  CA  LYS A  62      48.163
          ATOM   1780  HA  LYS A  62      49.236
          ATOM   1781  C   LYS A  62      47.633
          ATOM   1783  CB  LYS A  62      47.541
          ATOM   1784  HB2 LYS A  62      47.693
          ATOM   1785  HB3 LYS A  62      46.473
          ATOM   1798  HZ3 LYS A  62      45.853
          ATOM   1782  O   LYS A  62      47.789
          ATOM   1799  N   GLY A  63      47.001
          ATOM   1800  H   GLY A  63      46.906
      

      【讨论】:

        【解决方案3】:

        使用 perl 单行代码

        perl -ane '$F[2] eq "O" ? $o = $_ : print $F[2] eq "N" ? ($o, $_) : $_' file
        

        说明:

        开关

        • -a:在空间上分割行并将它们加载到数组中@F
        • -n:为输入文件中的每一行创建一个 while(<>){..} 循环。
        • -e:告诉perl 在命令行上执行代码。

        【讨论】:

          【解决方案4】:

          这应该可行:

          awk '$3 == "O" { T = $0; next; } $3 == "N" && T { print T; T = 0; } 1' your_file.txt
          

          精确输出:

              ATOM   1771  C   ALA A  61      48.797 
              ATOM   1772  O   ALA A  61      49.998 
              ATOM   1773  CB  ALA A  61      48.018 
              ATOM   1774  HB1 ALA A  61      48.964 
              ATOM   1775  HB2 ALA A  61      47.476 
              ATOM   1776  HB3 ALA A  61      47.420 
              ATOM   1777  N   LYS A  62      47.854 
              ATOM   1778  H   LYS A  62      46.979 
              ATOM   1779  CA  LYS A  62      48.163 
              ATOM   1780  HA  LYS A  62      49.236 
              ATOM   1781  C   LYS A  62      47.633 
              ATOM   1782  O   LYS A  62      47.789 
              ATOM   1783  CB  LYS A  62      47.541 
              ATOM   1784  HB2 LYS A  62      47.693 
              ATOM   1785  HB3 LYS A  62      46.473 
              ATOM   1798  HZ3 LYS A  62      45.853 
              ATOM   1799  N   GLY A  63      47.001 
              ATOM   1800  H   GLY A  63      46.906 
          

          【讨论】:

            【解决方案5】:

            这也应该有效,

            $ awk -v RS="\0" -v FS='\n' '{for (i=1;i<=NF; i++) {if ($i~/\s*ATOM\s*[0-9]+\s*O.*/) {var=$i;} else if($i~/\s*ATOM\s*[0-9]+\s*N.*/) {print var"\n"$i} else print $i;}}' file
                ATOM   1771  C   ALA A  61      48.797 
                ATOM   1773  CB  ALA A  61      48.018 
                ATOM   1774  HB1 ALA A  61      48.964 
                ATOM   1775  HB2 ALA A  61      47.476 
                ATOM   1776  HB3 ALA A  61      47.420 
                ATOM   1772  O   ALA A  61      49.998 
                ATOM   1777  N   LYS A  62      47.854 
                ATOM   1778  H   LYS A  62      46.979 
                ATOM   1779  CA  LYS A  62      48.163 
                ATOM   1780  HA  LYS A  62      49.236 
                ATOM   1781  C   LYS A  62      47.633 
                ATOM   1783  CB  LYS A  62      47.541 
                ATOM   1784  HB2 LYS A  62      47.693 
                ATOM   1785  HB3 LYS A  62      46.473 
                ATOM   1798  HZ3 LYS A  62      45.853 
                ATOM   1782  O   LYS A  62      47.789 
                ATOM   1799  N   GLY A  63      47.001 
                ATOM   1800  H   GLY A  63      46.906 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-08-12
              • 1970-01-01
              • 2021-04-02
              • 2015-05-12
              • 1970-01-01
              相关资源
              最近更新 更多