Text-Processing

用於在沒有互動式編輯器的情況下編輯配置文件值的命令行

  • April 6, 2021

許多配置文件是基於格式的Key value,或者Key=value每個配置文件都有一行。許多包提供了一個預設配置文件,其中這些可用的配置鍵已經用它們的預設值寫入和/或被註釋。

我想知道是否有一種工具可以更改此類文件而無需打開互動式編輯器並且比sed(可能建構在它之上)更高級別。

那將是簡單的:

$ conftool file key value

它會在文件中找到鍵,刪除註釋符號(如果有),更改值並保存結果。

據我所知,沒有通用的配置換行工具。我想創建這樣的工具會很困難,因為有很多不同的配置文件語法。

如果要更改特定配置文件中的特定值,則可以為該特定任務編寫專用工具。

這裡有兩個使用 sed 和 awk 的範例來幫助您入門

一個簡單的 sed 命令,用於替換鍵的值以獲得簡單的key value語法

$ sed 's/^key2 value2$/key2 newvalue2/' config 

例子

$ cat config 
key1 value1
key2 value2
key3 value3

$ sed 's/^key2 value2$/key2 newvalue2/' config 
key1 value1
key2 newvalue2
key3 value3

但請注意:如果有更多key2 value2行(可能在配置文件的其他部分),那麼所有行都將被替換。這在 sed 中很難防止(可能但很難),在 awk 中更容易。請參閱下面的有關部分的 awk 命令。

解釋:

此 sed 命令大致執行以下操作:

for every line:
 if line is "key2 value2":
   print "key2 newvalue2"

此 sed 命令s/pattern/replace/意味著:在每一行中搜尋pattern,如果找到,則替換為replace. pattern可以是普通字元串或正則表達式(正則表達式)。

正則表達式中的^and&被稱為錨點,分別表示行首和行尾。如果沒有錨,此模式key2 value2也將匹配此行xkey2 value2x,結果將是xkey2 newvalue2x.

這裡有一些例子,我們可以如何改變模式的行為。

也適用於key=value語法

$ sed 's/^key2=value2$/key2=newvalue2/' config 

無論舊值如何,都只匹配鍵

$ sed 's/^key2=.*/key2=newvalue2/' config 

刪除可能的評論標誌

$ sed 's/^#\?key2 value2$/key2 newvalue2/' config 

如果您重定向輸出,您還可以列印到 stderr

$ sed 's/^#\?key2 value2$/key2 newvalue2/ w /dev/stderr' config > newconfig

您可以使用正確的正則表達式做更多事情。但這將是另一個問題的另一個答案。

這是一個也可以處理配置部分的 awk 腳本

/^\[section2\]$/ {
 print
 insection2=1
 next
}
insection2 && /^#?key2=value2$/ {
 print "key2=newvalue2"
 next
}
/^\[.*\]$/ {
 insection2=0
}
1

像這樣使用

$ awk -f configer.awk config

例子

$ cat config 
[section1]
key1=value1
key2=value2

[section2]
key1=value1
key2=value2

[section3]
key1=value1
key2=value2

$ awk -f configer.awk config 
[section1]
key1=value1
key2=value2

[section2]
key1=value1
key2=newvalue2

[section3]
key1=value1
key2=value2

您還可以向 stderr 添加詳細輸出,以便在重定向輸出時查看發生了什麼變化

insection2 && /^#?key2=value2$/ {
 print "key2=newvalue2"
 print "changed line "NR > "/dev/stderr"
 next
}

awk 腳本的簡短說明

第一條規則查找[config2]節標題。它將insection2標誌設置為真

第二條規則查找該key2=value2行。但前提是insection2標誌為真。然後它將使用新值列印該行。

第三條規則查找任何其他節標題。它會將insection2標誌重置為假。

最後一條規則(唯一的1)是“預設規則”。它只會列印未更改的行。

在虛擬碼中

for every line:
 if line is [section2]:
   note that we are in section2
 else if we are in section2 and line is key2=value2:
   print modified line
 else if line is any other section header:
   note that we are no longer in section2
 else
   print line unchanged

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