102

How can I delete the first line of a file and keep the changes?

I tried this but it erases the whole content of the file.

$sed 1d file.txt > file.txt

11 Answers 11

78

The reason file.txt is empty after that command is the order in which the shell does things. The first thing that happens with that line is the redirection. The file "file.txt" is opened and truncated to 0 bytes. After that the sed command runs, but at the point the file is already empty.

There are a few options, most involve writing to a temporary file.

sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file

perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file
  • 2
    With BSD sed, you may use sed -i .bak '1d' file.txt. – user26112 Oct 16 '13 at 0:37
  • is there a way that does not include temp file? Anyway, this will do the trick. Thanks a lot! – kickass13 Oct 16 '13 at 0:38
  • @kickass13 possibly using a text editor such as ed. – jordanm Oct 16 '13 at 0:50
  • 5
    The ed command would be: printf "%s\n" 1d w q | ed file.txt (I heart ed) – glenn jackman Oct 16 '13 at 1:44
  • 1
    @jonayreyes -exec sed -i '1d' {} \; – jordanm Aug 28 '17 at 19:12
134

An alternative very lightweight option is just to 'tail' everything but the first line (this can be an easy way to remove file headers generally):

# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout

Following @Evan Teitelman, you can:

tail -n +2 file.txt | sponge file.txt

To avoid a temporary file. Another option might be:

echo "$(tail -n +2 file.txt)" > file.txt

And so forth. Testing last one:

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$ 

Oops we lost a newline (per @1_CR comment below), try instead:

printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5  

[user@work ~]$ 

Coming back to sed, try:

printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt

or perhaps

echo -e "$(sed '1d' file.txt)\n" > file.txt

To avoid side effects.

  • I've just tried it on my Fedora system and the output is above. You are correct - thanks for pointing that out. – AsymLabs Oct 16 '13 at 13:02
  • The tail trick worked for me (took less than 3 seconds on a 130mb file). Thanks! – elo80ka Aug 18 '14 at 17:51
  • echo "$(tail -n +2 file.txt)" > file.txt is the perfect answer. – Alex Raj Kaliamoorthy Nov 22 '16 at 12:26
  • Thank you! echo "$(tail -n +2 file.txt)" > file.txt works for me just like a charm! – Arsenii Feb 1 at 14:01
16

Also take a look at sponge from moreutils. sponge soaks in data from standard input until standard input's writing end closes before writing to a file. It is used like so:

sed '1d' file.txt | sponge file.txt
14

This topic is interest, so I test the benchmark in 3 ways:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. sed -i '1d' d.txt

Note that target d.txt is 5.4GB file

Get the result :


run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s

Conclusion : It seems below be the quickest way:

sed '1d' file.txt > tmpfile; mv tmpfile file.txt

  • Your sed '1d' d.txt method did not include (or so it seems by reading your tests) the mv command. In my tests on FreeBSD with a 20MB file the sed -i was the quickest. – Sopalajo de Arrierez Feb 11 '18 at 23:04
9

ex can be used for true in-place editing that does not involve a temp file

ex -c ':1d' -c ':wq' file.txt
  • 2
    ex does use a temp file. strace -e open ex -c ':1d' -c ':wq' foo. ex truncates the original file with the temp file, where as GNU sed's -i option overwrites the original with the temp file. I am not sure how BSD's sed works. – llua Dec 5 '13 at 16:03
  • @llua, you are right. I noticed that too, but later – iruvar Dec 5 '13 at 16:06
3

You can use Vim in Ex mode:

ex -s -c '1d|x' file.txt
  1. 1 find first line

  2. d delete

  3. x save and close

2

The shortest and simplest way to delete the first line from a file using sed is:

$ sed -i -n -e '2,$p' file.txt
0

This command will remove 1 line and save as "file.txt".

sed '1d' file.txt  > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
0

To Delete a praticiler line in file

  1. Delete first line

Sed '1d' file

  1. Delete first and third line

Sed '1d3d' file

Delete charecter in line

1 Delete First two charter in lin

Sed 's/^..//' file

2 Delete last two chrectercin line

Sed 's/..£//' file

3 Delete blank line

Sed '/^£/d' file

  • 4
    Did the British retake the colonies?  Last time I looked, £$. – G-Man Oct 22 '15 at 5:51
  • £ indicated doller sign.. – Vivek parikh Oct 22 '15 at 8:27
0

Could use vim to do this:

vim -u NONE +'1d' +wq! /tmp/test.txt
-2

cat file01 | sed -e '1,3d'

// show content in file01 but remove the first and third line

  • 2
    the sed command you give will remove lines 1, 2 and 3. – icarus Feb 10 '17 at 1:29
  • 1
    This deletes more than is asked for and does not "keep the changes " – Jeff Schaller Feb 10 '17 at 1:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.