简体   繁体   中英

Move last n lines of a text file to the top with Bash

How can I move last n lines of a text file to the top without knowing number of lines of the file? Is it possible to achieve this with single command line (with sed for example)?

From:

...
a
b
c
d

To:

a
b
c
d
...

Updated 2020:

You may find it hard if the input source is from pipe. In this case, you can use

awk '{a[NR-1]=$0}END{for(i=0;i<NR;++i)print(a[(i-4+NR)%NR])}'

This will store all lines in memory (which may be an issue) and then output them. Change 4 in the command to see different results.


Display the last n lines and then display the rest:

tail -n 4 file; head -n -4 file

From man head :

-n, --lines=[-]NUM

print the first NUM lines instead of the first 10; with the leading '-', print all but the last NUM lines of each file

tail -n 4 will display the last 4 lines of a file.

If you wish to pipe this data, you need to put them together like this:

( tail -n 4 file; head -n -4 file ) | wc

Or maybe you can use vim to edit file inline:

vim +'$-3,$m0' +'wq' file

The + option for vim will run the (Ex) command following it. $-3,$m0 means move lines between 3 lines above the last line and the last line to the beginning of the file. Note that there should be no space between + and the command.


Or using commands in vim normal mode:

vim +'norm G3kdGggPZZ' file

G go to file end; 3k move up 3 lines; dG deletes to file end; gg go to file top; P pastes the deleted lines before this line; ZZ saves and quits.

This might work for you (GNU sed):

sed '$!H;1h;$!d;G' file

Append every line but the last to the hold space and then append the hold space to the the last line.

It is trivial to do with ed

Move the last 30 lines on top of the file.

printf '%s\n' '30,$m0' ,p Q | ed -s file.txt

Move 10 to 50 lines on top of the file.

printf '%s\n' '10,50m0' ,p Q | ed -s file.txt

Move 1 to 10 to the last line/buffer.

printf '%s\n' '1,10m$' ,p Q | ed -s file.txt

Move 40 to 80 at the last line/buffer

printf '%s\n' '40,80m$' ,p Q | ed -s file.txt
  • Line address 0 is the first and m means move

  • $ is the last line of the buffer/file.

  • Change Q to w to actually edit the file.txt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM