可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to remove some n lines from the end of a file. Can this be done using sed?
For example, to remove lines from 2 to 4, I can use
$ sed '2,4d' file
But I don't know the line numbers. I can delete the last line using
$sed $d file
but I want to know the way to remove n lines from the end. Please let me know how to do that using sed or some other method.
回答1:
I don't know about sed
, but it can be done with head
:
head -n -2 myfile.txt
回答2:
From the sed one-liners:
# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
Seems to be what you are looing for.
回答3:
If hardcoding n is an option, you can use sequential calls to sed. For instance, to delete the last three lines, delete the last one line thrice:
sed '$d' file | sed '$d' | sed '$d'
回答4:
A funny & simple sed
and tac
solution :
n=4
tac file.txt | sed "1,$n{d}" | tac
NOTE
- double quotes
"
are needed for the shell to evaluate the $n
variable in sed
command. In single quotes, no interpolate will be performed.
tac
is a cat
reversed, see man 1 tac
- the
{}
in sed
are there to separate $n
& d
(if not, the shell try to interpolate non existent $nd
variable)
回答5:
Use sed
, but let the shell do the math, with the goal being to use the d
command by giving a range (to remove the last 23 lines):
sed -i "$(($(wc -l < file)-22)),\$d" file
To remove the last 3 lines, from inside out:
$(wc -l < file)
Gives the number of lines of the file: say 2196
We want to remove the last 23 lines, so for left side or range:
$((2196-22))
Gives: 2174
Thus the original sed after shell interpretation is:
sed -i 2174,$d file
With -i
doing inplace edit, file is now 2173 lines!
回答6:
You could use head for this.
Use
$ head --lines=-N file > new_file
where N is the number of lines you want to remove from the file.
The contents of the original file minus the last N lines are now in new_file
回答7:
Just for completeness I would like to add my solution.
I ended up doing this with the standard ed
:
ed -s sometextfile <<< $'-2,$d\nwq'
This deletes the last 2 lines using in-place editing (although it does use a temporary file in /tmp
!!)
回答8:
This might work for you (GNU sed):
sed ':a;$!N;1,4ba;P;$d;D' file
回答9:
To truncate very large files truly in-place we have truncate
command.
It doesn't know about lines, but tail
+ wc
can convert lines to bytes:
file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file
There is an obvious race condition if the file is written at the same time.
In this case it may be better to use head
- it counts bytes from the beginning of file (mind disk IO), so we will always truncate on line boundary (possibly more lines than expected if file is actively written):
truncate -s $(head -n -$lines $file | wc -c) $file
Handy one-liner if you fail login attempt putting password in place of username:
truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure
回答10:
With the answers here you'd have already learnt that sed is not the best tool for this application.
However I do think there is a way to do this in using sed; the idea is to append N lines to hold space untill you are able read without hitting EOF. When EOF is hit, print the contents of hold space and quit.
sed -e '$!{N;N;N;N;N;N;H;}' -e x
The sed command above will omit last 5 lines.
回答11:
Most of the above answers seem to require GNU commands/extensions:
$ head -n -2 myfile.txt
-2: Badly formed number
For a slightly more portible solution:
perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'
OR
perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'
OR
awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'
Where "10" is "n".
回答12:
Try the following command:
n = line number
tail -r file_name | sed '1,nd' | tail -r
回答13:
You can get the total count of lines with wc -l <file>
and use
head -n <total lines - lines to remove> <file>
回答14:
It can be done in 3 steps:
a) Count the number of lines in the file you want to edit:
n=`cat myfile |wc -l`
b) Subtract from that number the number of lines to delete:
x=$((n-3))
c) Tell sed to delete from that line number ($x
) to the end:
sed "$x,\$d" myfile
回答15:
I prefer this solution;
head -$(gcalctool -s $(cat file | wc -l)-N) file
where N is the number of lines to remove.
回答16:
sed -n ':pre
1,4 {N;b pre
}
:cycle
$!{P;N;D;b cycle
}' YourFile
posix version
回答17:
To delete last 4 lines:
$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'
回答18:
I came up with this, where n is the number of lines you want to delete:
count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt
It's a little roundabout, but I think it's easy to follow.
- Count up the number of lines in the main file
- Subtract the number of lines you want to remove from the count
- Print out the number of lines you want to keep and store in a temp file
- Replace the main file with the temp file
- Remove the temp file
回答19:
This will remove the last 3 lines from file
:
for i in $(seq 1 3); do sed -i '$d' file; done;
回答20:
This will remove the last 12 lines
sed -n -e :a -e '1,10!{P;N;D;};N;ba'