3

This question already has an answer here:

How do I delete a line only if it is at a specified line number and it matches the pattern?


For example:

  • I want to delete (d);
  • the third line (3);
  • if it's blank (^$);

The following syntax:

cat file | sed '3 /^$/d'

Returns the following error:

sed: -e expression #1, char 3: unknown command: `/'

marked as duplicate by Anthon, Thomas Dickey, Stephen Kitt, Anthony Geoghegan, GAD3R Oct 3 '16 at 11:14

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 2
    Don't you mean third line if it is blank? – Kaz Oct 3 '16 at 3:14
  • 1
    What's the special use of cat in your example? Any reason to complicate things and not run sed '3 /^$/d' file? – Anthon Oct 3 '16 at 6:35
  • Like Kaz, I'm puzzled by the code, given the stated interest in deleting the first line. Pretty clearly, though, the code is pointing to line 3. – Dɑvïd Oct 3 '16 at 8:05
  • 1
    I may be blind but I don't see how the answers to the linked question really showing how to combine both a line number match and a pattern match. The closest is this: sed -i '4s/foo/bar/g' file (substitute only on one line), but that only works since s/// is an operation, and a no-op if it doesn't match. (So yah, voted for reopen) – ilkkachu Oct 3 '16 at 12:13
  • 1
    FWIW, I voted to close this question as unclear due to the confusion over which line should be deleted (my vote was lumped in with the duplicate votes). Since tjt263's edit removes the ambiguity, I'm now voting to re-open. – Anthony Geoghegan Oct 3 '16 at 14:02
10

Try doing this:

sed '3{/^$/d;}' file

Note the braces.

  • 9
    Since this answer currently contains no explanation what-so-ever: Both line numbers (the 3) and patterns (the /^$/) are ways of specifying how to match lines: each command can only be preceded by one way of matching. Fortunately, brackets create a group of commands that can go anywhere a single command can go. So you can do 42 { /regex/ d }, or /regex/ { 42 d }, or nest them for more complex situations: /foo/ { 1 { /bar/ d }; $ { /qux/ d } } – mtraceur Oct 2 '16 at 16:38
  • Thanks. I didn't know you could use the braces like that. – voices Oct 3 '16 at 11:04
3

Like user000001 answered, sed '3{/^$/d;}' file is good enough, but it will only show you that output. If you want to modify the file, and your sed is the GNU sed, you can use sed -i '3{/^$/d}' file (for GNU sed, the ; before } can also be omitted here).

`-i[SUFFIX]'
`--in-place[=SUFFIX]'
     This option specifies that files are to be edited in-place.  GNU
     `sed' does this by creating a temporary file and sending output to
     this file rather than to the standard output.(1).

With FreeBSD/OS/X sed, use sed -i '' '3{/^$/d;}' file.

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