Awk

匹配一個模式並替換以下鍵值對的值

  • May 4, 2021

我正在嘗試修改包含以下部分的文件:

[ 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                    = myemail@email.com

我想修改common name最後一節中欄位的值。

我認為應該有一個類似於這個解決方案的解決方案。

sed'/

$$ shovel $$/,/^$/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                    = myemail@email.com

GNU sed在擴展正則表達式模式下-E,我們使用範圍運算符,選擇正確的塊,並在該塊內使用**s/regex/repl/**的正則表達式在右側行中歸零以進行編輯。

sed -Ee '
 /\[ req_distinguished_name ]/,/^$/s/^(\s*commonName\s*=).*/\1__NEWVALUE__/
' file

假設您要替換文件中屬性 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

如果您只想替換最後一個,那麼最簡單的方法是跳過程序的早期部分,直到找到 section 標記,然後使用上面的 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”中。

這應該非常接近你想要的。

引用自:https://unix.stackexchange.com/questions/647935