3

I have something like

dsadjakldjska
safdsfdsfsf
fdsfsf**STGN**fdsfsd
fdsfkjldsf
fdsff
fdsfs**IRV**fdsfs

and I want to get

dsadjakldjska
safdsfdsfsf
fdsfkjldsf
fdsff
fdsfsf**STGN**fdsfsd
fdsfs**IRV**fdsfs

but only for an interval of lines (say line 40000 till end of file) (moving the line containing STGN right above the next IRV underneath it)

Any idea how I can do this, or whether there's a better alternative for this than sed?

3
awk 'NR < 40000 {print; next}
     /\*\*STGN\*\*/ {line = $0; next}
     /\*\*IRV\*\*/ && line {print line; line=""}
     {print}'

With sed:

sed -e '40000,$!b' -e '/\*\*STGN\*\*/{h;d;}' -e '/\*\*IRV\*\*/{x;/./p;s/.*//;x;}'

(they assume the STGN occurs before the IRV).

  • For my own education, what is the reason to use {x;/./p;s/.*//;x;} rather than the apparently simpler {x;G;}? – steeldriver Aug 12 '14 at 15:36
  • @steeldriver That's so as not to insert the hold space if it's empty (if no STGN was found) and to reset it to the empty string for the next occurrence. That's the equivalent of the && line and line = "" in the awk one. If there's only one STGN and only one IRV and they occur in that order, then {x;G;} works just as well. – Stéphane Chazelas Aug 12 '14 at 15:53
  • What if STGN occurs after IRV? – Giovanni Lovato Oct 21 '18 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.