iniファイルは複数のセクションが同じ名前のキーを持つことがあり、そのような場合1箇所だけ変更したくしても単純なsedの置換を使用するとまとめて変更されてしまう。

そのようなiniファイルの例としてはCentOSの/etc/yum.repos.d/CentOS-Base.repoなどがある。
これを例えばextrasセクションのenabledだけを0にしたい、ということがあるわけだ。1

/etc/yum.repos.d/CentOS-Base.repo(コメント行を省略)
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

このような状況でsedを使って変更したい場合、アドレスの範囲指定を使うと良い。
例えば以下のようになるだろう。

# sed -ri '/^[extras]$/,/^[/ s/^(enabled)( *)=.*$/12=20/' /etc/yum.repos.d/CentOS-Base.repo

範囲指定を行っている箇所は/^[extras]$/,/^[/である。
つまり/^[extras]$/にマッチする行から、それ以降の/^[/までにマッチする行までをsedの処理対象にするというわけである。

つまり上記iniファイルだと以下の行だけが処理対象になる。
この範囲にはenabledという名前のキーは1回しか現れないため、1箇所だけを変更することが可能である、というわけである。

[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[centosplus]

なお、この方法はiniファイルの一番最後のセクションに対しても使用できる。
範囲指定の前半の正規表現にマッチする行以降に、後半の正規表現にマッチするものが現れない場合は最終行までが範囲になるからである。

従ってcentosplusセクションのenableを1にしたい場合はこのように書くことができる。

# sed -ri '/^[centosplus]$/,/^[/ s/^(enabled)( *)=.*$/12=21/' /etc/yum.repos.d/CentOS-Base.repo

extrasとcentosplusを2つ同時に変更したければsedスクリプト内で単純に;で区切れば良い。

# sed -ri '/^[extras]$/,/^[/ s/^(enabled)( *)=.*$/12=20/; /^[centosplus]$/,/^[/ s/^(enabled)( *)=.*$/12=21/' /etc/yum.repos.d/CentOS-Base.repo


  1. 実際のところこれを行う場合、yum-utilsがインストールされていればyum-config-manager --disable extras、あるいはdnfならdnf config-manager --set-disabled extrasで良いが、この記事の俎上に載せるのにふさわしいiniファイルの例として他にあまり良いものが思いつかなかった。 

TOP