Reputation: 31
I'm trying to create a script that will replace the parameters of a given network interface in the 01-network-manager-all.yaml
file.
The file looks something like this:
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses: [195.10.10.10/24]
gateway4: 195.10.10.10
nameservers:
addresses: [1.1.1.1]
enp0s8:
dhcp4: no
dhcp6: no
addresses: [196.10.10.10/24]
gateway4: 196.10.10.10
nameservers:
addresses: [1.1.1.1]
enp0s9:
dhcp4: no
dhcp6: no
addresses: [197.10.10.10/24]
gateway4: 197.10.10.10
nameservers:
addresses: [1.1.1.1]
Say I want to replace the lines concerning enp0s8
and leave the others as they are.
The output would look something like this:
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses: [195.10.10.10/24]
gateway4: 195.10.10.10
nameservers:
addresses: [1.1.1.1]
enp0s8:
dhcp4: no
dhcp6: no
addresses: [196.250.250.125/24]
gateway4: 196.250.250.125
nameservers:
addresses: [8.8.8.8]
enp0s9:
dhcp4: no
dhcp6: no
addresses: [197.10.10.10/24]
gateway4: 197.10.10.10
nameservers:
addresses: [1.1.1.1]
In this case, I'm looking for a sed
- or any other command - that will replace everything in between enp0s8
and enp0s9
.
I'm not a very experienced Bash user, any tip will be appreciated.
My poor attempt at doing so
sed -e '/^ *enp0s8:/,/^ *^enp0s9:/s/$CONFIG_TO_ADD/' "/etc/netplan/01-network-manager-all.yaml"
Upvotes: 3
Views: 397
Reputation: 26727
Using yq :
yq eval '.network.ethernets.enp0s8 |= (.addresses = ["196.250.250.125/24"] |
.gateway4 = "196.250.250.125" |
.nameservers.addresses = ["8.8.8.8"]
)' file.yml
Upvotes: 3
Reputation: 7831
Just in case someone is interested.
Using ed
if available/acceptable.
#!/bin/sh
ethernets=enp0s8
gateway=196.250.250.125
address=196.250.250.125/24
name_server_address=8.8.8.8
ed -s file.yaml <<-EOF
g/$ethernets/;/nameservers/s/^\\([[:blank:]]*gateway4:[^ ]*\\).*/\\1 $gateway/\\
-1s|^\\([[:blank:]]*addresses: \[\\).*\\(\]\\)$|\\1$address\\2|
g/$ethernets/;/nameservers:/;/addresses:/s|^\\([[:blank:]]*addresses: \\[\\).*\\(\\]\\)$|\\1$name_server_address\\2|
,p
Q
EOF
Change the last digit of enp0s
if the changes should be made at the other section/block, which is pointing to enp0s8
right now.
Not a yaml
parser/editor and not robust as the other solutions but It can do the job.
Upvotes: 1
Reputation: 204426
$ cat new
dhcp4: no
dhcp6: no
addresses: [196.250.250.125/24]
gateway4: 196.250.250.125
nameservers:
addresses: [8.8.8.8]
$ awk '
NR==FNR { new=new ORS $0; next }
/^ [^ ]/ { if ( f=($1=="enp0s8:") ) print $0 new }
!f
' new file
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses: [195.10.10.10/24]
gateway4: 195.10.10.10
nameservers:
addresses: [1.1.1.1]
enp0s8:
dhcp4: no
dhcp6: no
addresses: [196.250.250.125/24]
gateway4: 196.250.250.125
nameservers:
addresses: [8.8.8.8]
enp0s9:
dhcp4: no
dhcp6: no
addresses: [197.10.10.10/24]
gateway4: 197.10.10.10
nameservers:
addresses: [1.1.1.1]
Upvotes: 2
Reputation: 247092
I'd use a tool that understands YAML instead of plain text manipulation. For example, ruby:
$ ruby -e '
require "yaml"
data = YAML.safe_load_file(ARGV[0])
net = data["network"]["ethernets"]["enp0s8"]
net["addresses"] = ["196.250.250.125/24"]
net["gateway4"] = "196.250.250.125"
net["nameservers"]["addresses"] = ["8.8.8.8"]
puts data.to_yaml
' file.yml
---
network:
version: 2
renderer: NetworkManager
ethernets:
enp0s3:
dhcp4: false
dhcp6: false
addresses:
- 195.10.10.10/24
gateway4: 195.10.10.10
nameservers:
addresses:
- 1.1.1.1
enp0s8:
dhcp4: false
dhcp6: false
addresses:
- 196.250.250.125/24
gateway4: 196.250.250.125
nameservers:
addresses:
- 8.8.8.8
enp0s9:
dhcp4: false
dhcp6: false
addresses:
- 197.10.10.10/24
gateway4: 197.10.10.10
nameservers:
addresses:
- 1.1.1.1
Upvotes: 3