1

I have a file testfile.txt containing

pippo=x
pluto=y
1234=z

I'd like to delete only the first line matching /^[a-z]\+=/ (the first line in this example).

I've tried with the following command but without success:

sed   '/^[a-z]\+=/,+0d' testfile.txt

but the first two lines are deleted.

Is there a way to do this task using sed?

Regards

  • To delete only the first line and only if it contains an assignment that starts in the first column, try sed '1{/^[a-z]\+=/d}' testfile.txt. (The code that you have works fine for me with GNU sed but other versions of sed treat line number 0 differently.) – John1024 Jun 22 '16 at 10:41
2

The issue with your sed command

$ sed '/^[a-z]\+=/,+0d' testfile.txt

is that the sed script is applied to every line of the input data.

The +0 (which is a GNU extension) means that your script is equivalent to

$ sed '/^[a-z]\+=/d' testfile.txt

and the first and second lines would be deleted, as you noticed.

Incidentally, you will get exactly the same effect using +1, but for other reasons. The d command would, instead of being applied to line one and two individually, be applied to the first two lines because of the match on the first line (i.e. the range of the d command would be lines one and one more, +1). This doesn't delete line three because it's outside of the range.

The GNU sed solution

$ sed '0,/^[a-z]\+=/{//d}' testfile.txt

that user @Whitefield posted works and is rather good (although the -r option is unnecessary and the 0 start address may be changed to 1 in this case, if you want to be more POSIX-ish).

A BSD sed variant of the same approach would look like

$ sed '1,/^[a-z]+=/{/^[a-z]+=/d
  }' testfile.txt

Escaping the + is only necessary if your sed implements "obsolete basic regular expressions" rather than "modern basic regular expressions". Both BSD sed and GNU sed on my system (Mac OS X) seems to be of the "modern" kind. POSIX doesn't have this distinction, and reading the manuals (re_format(7) on BSD, which makes this distinction) and the POSIX specification side-by-side makes my head spin.

1

@John1024 I'm sorry but your solution works only if the first matching line is the first line of the file.

I solved the problem with the following code sed -r '0,/^[a-z]\+=/{//d;}' testfile.txt but I'm still convinced that my previous solution should have worked even with posix sed.

Infacts the idea was to give as second line address an offset of 0 lines... but it still deletes also the following line, this sounds like a bug.

from man sed in ubuntu 14.04

... addr1,+N Will match addr1 and the N lines following addr1. ...

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.