5

The standard format of the file is:

Host example
  HostName example.com
  Port 2222
Host example2
  Hostname two.example.com

Host three.example.com
  Port 4444

Knowing the host's short name, I want to remove an entire entry in order to re-add it with new details.

The closest I have got is this, except I need to keep the following Host declaration and the second search term will capture two many terms (like HostName):

sed '/Host example/,/\nHost/d'
Ryan
  • 4,594
  • 1
  • 32
  • 35
  • In the general case, you need a parser for this file format. There is no guarantee that entries will be indented, or that indented lines are part of a preceding entry, let alone that the next top-level directive will be a `Host` directive. – tripleee Mar 20 '16 at 10:04

2 Answers2

6

With GNU sed:

host="example"
sed 's/^Host/\n&/' file | sed '/^Host '"$host"'$/,/^$/d;/^$/d'

Output:

Host example2
  Hostname two.example.com
Host three.example.com
  Port 4444

s/^Host/\n&/: Insert a newline before every line that begins with "Host"

/^Host '"$host"'$/,/^$/d: delete all lines matching "Host $host" to next empty line

/^$/d: clean up: delete every empty line

Community
  • 1
  • 1
Cyrus
  • 84,225
  • 14
  • 89
  • 153
2

My final solution (which is somewhat OSX orientated) was this. It's largely based on Cyrus' earlier answer.

sed < $SOURCE "/^$/d;s/Host /$NL&/" | sed '/^Host '"$HOST"'$/,/^$/d;' > $SOURCE

This is more resilient to HostName directives which aren't indented.

Ryan
  • 4,594
  • 1
  • 32
  • 35