Awk
匹配一個模式並替換以下鍵值對的值
我正在嘗試修改包含以下部分的文件:
[ 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”中。
這應該非常接近你想要的。