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
...
Using vim's ex mode is even simpler: (inspired by this answer)
vim - -esc '$-3,$m0|%p|q!' --not-a-term # when processing a pipe
vim file.txt -esc '$-3,$m0|%p|q!' --not-a-term # when processing a file to stdout
vim file.txt -esc '$-3,$m0|wq' --not-a-term # when editing a file inline
This will move last 4 lines (last line + 3 lines before the last line) to top. Change 3
to your desired number.
A MWE:
seq 10 | vim - '-esc$-3,$m0|%p|q!' --not-a-term
Output:
7
8
9
10
1
2
3
4
5
6
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With