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?

1 Answer 1

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).

3
  • For my own education, what is the reason to use {x;/./p;s/.*//;x;} rather than the apparently simpler {x;G;}? Commented Aug 12, 2014 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. Commented Aug 12, 2014 at 15:53
  • What if STGN occurs after IRV? Commented Oct 21, 2018 at 5:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .