Переместить строку, соответствующую определенному шаблону, в другую строку, соответствующую другому шаблону, используя sed

#regex #perl #bash #sed #pattern-matching

#регулярное выражение #perl #bash #sed #сопоставление с шаблоном

Вопрос:

Я новичок в 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 
  

Есть предложения? Большое спасибо за ваше время!

Ответ №1:

Использование однострочного perl

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

Объяснение:

Переключатели:

  • -a : Разбивает строку на пробел и загружает их в массив @F
  • -n : Создает while(<>){..} цикл для каждой строки во входном файле.
  • -e : Указывает perl на выполнение кода в командной строке.

Ответ №2:

Это должно сработать:

 awk '$3 == "O" { T = $0; next; } $3 == "N" amp;amp; 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 
  

Ответ №3:

Это также должно работать,

 $ awk -v RS="" -v FS='n' '{for (i=1;i<=NF; i  ) {if ($i~/s*ATOMs*[0-9] s*O.*/) {var=$i;} else if($i~/s*ATOMs*[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 
  

Ответ №4:

Другой 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
  

Ответ №5:

Это может сработать для вас (GNU sed):

 sed '/sOs/{h;d};/sNs/{H;x}' file
  

Сохраните O строку в пространстве удержания, а затем удалите ее, добавьте к N ней строку и распечатайте одновременно.