Reputation: 164
I am a beginner in sed and awk, however I can do basic tasks. I have a problem with my work that involves rearranging certain lines in a file from one place to another.
In the following example, I would like to capture the line containing the patterns " O " (with whitespaces), and move it before the line containing pattern " N " so that:
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
becomes:
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
Any suggestions? Thanks a lot for your time!
Upvotes: 0
Views: 98
Reputation: 58391
This might work for you (GNU sed):
sed '/\sO\s/{h;d};/\sN\s/{H;x}' file
Save the O
line in the hold space and then delete it, append the N
line to it and print out at the same time.
Upvotes: 1
Reputation: 41456
Another 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
Upvotes: 1
Reputation: 35198
Using a perl one-liner
perl -ane '$F[2] eq "O" ? $o = $_ : print $F[2] eq "N" ? ($o, $_) : $_' file
Switches:
-a
: Splits the line on space and loads them in an array @F
-n
: Creates a while(<>){..}
loop for each line in your input file. -e
: Tells perl
to execute the code on command line. Upvotes: 2
Reputation: 75478
This should work:
awk '$3 == "O" { T = $0; next; } $3 == "N" && T { print T; T = 0; } 1' your_file.txt
Exact output:
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
Upvotes: 2
Reputation: 174706
This also shoul work,
$ 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
Upvotes: 1