3

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: `/'
voices
  • 1,272
user123456
  • 5,018
  • 2
    Don't you mean third line if it is blank? – Kaz Oct 03 '16 at 03: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 03 '16 at 06: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 03 '16 at 08: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 03 '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 03 '16 at 14:02

2 Answers2

10

Try doing this:

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

Note the braces.

user000001
  • 3,635
  • 10
    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 02 '16 at 16:38
  • Thanks. I didn't know you could use the braces like that. – voices Oct 03 '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.

Jaur
  • 354