我正在尝试修改包含如下部分的文件:
[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req_distinguished_name ]
countryName = UK
stateOrProvinceName = Scotland
localityName = Glasgow
0.organizationName = aworkplace
organizationalUnitName = eng
commonName = my.webiste.com
emailAddress = [email protected]
我想修改common name
最后一节中字段的值。
我认为应该有一个类似的解决方案这个解决方案。
sed '/[铲子]/,/^$/ s/启用 = 0/启用 = 1/'
不同之处在于,被替换的值不是 sed 命令中匹配的表达式的一部分。
更新
根据评论进行一些澄清,目标是仅更改commonName
该req_distinguished_name
部分中的字段。例如
[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req_distinguished_name ]
countryName = UK
stateOrProvinceName = Scotland
localityName = Glasgow
0.organizationName = aworkplace
organizationalUnitName = eng
commonName = adifferentvaluetotheoneintheabovesnippet
emailAddress = [email protected]
答案1
GNU sed在扩展正则表达式模式下,-E
我们使用范围运算符,
来选择正确的块,并在该块内使用s/正则表达式/repl/将右行归零以进行编辑。
sed -Ee '
/\[ req_distinguished_name ]/,/^$/s/^(\s*commonName\s*=).*/\1__NEWVALUE__/
' file
答案2
假设您想要替换文件中属性 commonName 的值,并且您愿意替换如此命名的任何属性的所有值,则以下操作应该有效(并假设 PCRE):
s/(^commonName\s+=\s*)(.*)$/\1<your replacement text here>/
例如,假设您想要设置新值“foo”,那么您的示例文件将运行以下内容:
s/(^commonName\s+=\s*)(.*)$/\1foo/
应该导致所有其他行保持不变,并且 commonName 值全部替换为:
commonName = foo
commonName = foo
and
commonName = foo
如果您只想替换最后一个,那么最简单的方法是跳过程序的早期部分,直到找到节标记,然后使用上面的 s/// 结构替换第一个匹配项,然后停止编辑。
更新:如上所述,您应该能够在(例如 PERL)中完成此操作,方法是首先找到要编辑的块的块头,然后编辑(应用正则表达式替换)直到到达下一个块头,然后忽略文件的其余部分。在 Perl 中,这可能看起来像:
#!/usr/bin/env perl -pi.orig
while (<> !~ /\[ req_distinguished_name \]/) { # do nothing
};
while (<> !~ /^\[\s*[\w\d_+]\s*\]/) { s/^(commonName\s*=\s*)(.*)$/\1<repl>/; }
while (!eof()) { <>; }
这将编辑命令行参数中指定的文件,并将未修改文件的备份副本保存在“.orig”中。
这应该非常接近你想要的。