Command Line Text Processing – Move First N Lines of Output to End Without Temporary File

command linetext processing

Imagine an output of a command like

44444
55555
11111
22222
33333

how can I yank the first N lines (first two in the example above) and append them at the end, but without using temp file (so only using pipes)?

11111
22222
33333
44444
55555

Something along the lines of | sed -n '3,5p;1,2p' (which obviously doesn't work as sed doesn't care about the order of the commands).

Best Answer

Just copy those lines to the hold buffer (then delete them) and when on last line append the content of hold buffer to pattern space:

some command | sed '1,NUMBER{           # in this range
H                                       # append line to hold space and
1h                                      # overwrite if it's the 1st line
d                                       # then delete the line
}
$G'                                     # on last line append hold buffer content

With gnu sed you could write it as

some command | sed '1,NUMBER{H;1h;d;};$G'

Here's another way with ol' ed (it reads the output of some command into the text buffer and then moves lines 1,NUMBER after the la$t one):

ed -s <<IN
r ! some command
1,NUMBERm$
,p
q
IN

Note that - as pointed out - these will both fail if the output has less than NUMBER+1 lines. A more solid approach would be (gnu sed syntax):

some command | sed '1,NUMBER{H;1h;$!d;${g;q;};};$G'

this one only deletes lines in that range as long as they're not the last line ($!d) - else it overwrites pattern space with hold buffer content (g) and then quits (after printing the current pattern space).

Related Question