67

I'm using sed to filter a list of files. I have a sorted list of folders and I want to get all lines after a specific one. To do this task I'm using the solution described here which works pretty well with any input I tried but it doesn't work when the match is on the first line. In that case sed will remove all lines of the input

Here it's an example:

$ ls -1 /
bin
boot
...
sys
tmp
usr
var
vmlinuz

$ ls -1 / | sed '1,/tmp/d'
usr
var
vmlinuz

$ ls -1 / | sed '1,/^bin$/d'
# sed will delete all lines from the input stream

How should I change the command to consider also the limit case when first line is matched by regexp?

BTW sed '1,1d' correctly works and remove the first line only.

oguz ismail
  • 1
  • 16
  • 47
  • 69
Fabio
  • 18,856
  • 9
  • 82
  • 114

4 Answers4

72

try this (GNU sed only):

sed '0,/^bin$/d'

..output is:

$sed '0,/^bin$/d' file
boot
...
sys
tmp
usr
var
vmlinuz
Endoro
  • 37,015
  • 8
  • 50
  • 63
  • This seems the best option. I saw your previous answer which states that it works for GNU sed, now you removed that. I'm using GNU sed, so for me this is the right answer, but just for curiosity, will it work for non GNU sed? – Fabio Jun 28 '13 at 12:54
  • there is no GNU specific command, it should work, told me my text book. – Endoro Jun 28 '13 at 12:58
  • It doesn't work on OS X sed, but as I told you I need it on a gnu system. – Fabio Jun 28 '13 at 13:02
  • Argh! `0,/_Address_/` **is** GNU enhancement, should work for you. – Endoro Jun 28 '13 at 13:03
  • Should start from 1 on BSD/OS X: `sed '1,/Whatever/d'`. – Morten Oct 06 '16 at 15:53
  • 1
    For completeness. To **delete all lines following a certain pattern** `something` do: `sed -E '/^something$/,$d'`, where `-E` is the POSIX portability extended regex. – not2qubit Nov 17 '18 at 15:19
  • 1
    Alternative for BSD sed (mac users): `sed -n '/^bin$/,$p'`. `-n` says print nothing by default, until you hit the then matching line then print `p` everything. – John Jones Nov 08 '22 at 21:11
63

This sed command will print all lines after and including the matching line:

sed -n '/^WHATEVER$/,$p'

The -n switch makes sed print only when told (the p command).

If you don't want to include the matching line you can tell sed to delete from the start of the file to the matching line:

sed '1,/^WHATEVER$/d'

(We use the d command which deletes lines.)

ase
  • 13,231
  • 4
  • 34
  • 46
  • I've explored also this option and i quit because of inclusion of matching line. I missed the `tail -n +2` option. So this is also good. Thanks. – Fabio Jun 28 '13 at 13:00
  • You save my day. Very simple to understand and full fonctional. Surely the best answer if matching line should be included. – jmcollin92 Jun 16 '16 at 09:50
  • Actually, if you use the -n syntax, it will include the matching line. If you use the second form ( sed '1,/^WHATEVER$/d'), it will not. (Tested on sed 4.2.2, on RHEL 7 Linux). – HAltos Dec 18 '20 at 19:57
  • What is the difference between sed '1,/^WHATEVER$/d' and sed '0,/^WHATEVER$/d' ? They produce the same result for me – Joe Jobs Dec 31 '20 at 21:51
13

you can also try with :

awk '/searchname/{p=1;next}{if(p){print}}'

EDIT(considering the comment from Joe)

awk '/searchname/{p++;if(p==1){next}}p' Your_File
Vijay
  • 65,327
  • 90
  • 227
  • 319
  • This script works, however it deletes the "searchname" everywhere after the first occurrence. The other solutions do not delete them, they delete only the first occurrence and the lines before it – Joe Jobs Dec 31 '20 at 20:43
1

I would insert a tag before a match and delete in scope /start/,/####tag####/.

Jacek Krysztofik
  • 1,266
  • 1
  • 13
  • 29