我有一个文件 “input.txt” ,它在行号18处包含以下内容:

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth =“Admin”

我要替换 "Admin" with {"Admin", "root"}--->“root”只是一个示例名称,可以是任何名称。

因此,更换后,行号18 应该变为

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth = {“Admin”,“root”}

使用不同输入名称的sed命令的另一次运行:“user1”

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth = {“Admin”,“root”,“user1”}

依此类推,该文件的行号18 可以有多个条目 input.txt

...

我也想删除它。

也就是说,如果文件“input.txt” 行号中包含以下内容:18

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth = {“Admin”,“root”,“user1”}

然后在删除“root” 后,它应变为:

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth = {“Admin”,“user1”}

删除“user1” 后,它应变为:

条目({“servicectl”},别名(“servicectl”,“status”))。sysauth =“Admin”

最佳答案

如果我正确理解您想要什么:从此输入文件开始:

# file input.txt
# line 1
# line ...
# line 17
entry({"servicectl"}, alias("servicectl", "status")).sysauth = "Admin"

使用此sed指令(具有宽松的空间公差):
ENTRY='new_user' && sed '18s/=\s*{\?\s*\(".*"\)\s*}\?\s*/= {\1, "'"${ENTRY}"'"}/' input.txt > output.txt

要获得此:
# file output.txt
# line 1
# line ...
# line 17
entry({"servicectl"}, alias("servicectl", "status")).sysauth = {"Admin", "new_user"}

根据您的要求,您可以多次应用sed命令以将新条目追加到第18行。

然后,您可以这样删除最后一个条目(直到最终返回到原始的input.txt):
sed '18s/=\s*{\s*\("[^"]*"\)\s*,\s*\("[^"]*"\)\s*}/= \1/; 18s/=\s*{\s*\("[^"]*"\)\(\(\s*,\s*"[^"]*"\)\{1,\}\)\s*,\s*"[^"]*"\s*}/= { \1\2 }/' output.txt

为了删除条目,我考虑了两种情况:只有一个${ENTRY}(要知道何时删除花括号)和何时有两个或更多重复的${ENTRY}

更新此版本的,类似于adduser版本,接受shell变量以删除特定用户:
ENTRY='user3' && sed '18s/=\s*{\s*\("[^"]*"\)\s*,\s*\("'"${ENTRY}"'"\)\s*}/= \1/; 18s/=\s*{\s*\("[^"]*"\)\(.*\)\(\s*,\s*"'"${ENTRY}"'"\)\(.*\)\s*}/= { \1\2\4 }/' output.txt

它有效,仅注意我认为管理员不可修改。

注意:注意,remove sed regex不需要您之前检查该行:如果该行以单个...= "Admin"结尾,则什么也不会发生。

UPDATE-2 :从Ed Morton那里得到的提示,您还可以将这两个函数放入${HOME}/.bashrc(如果使用其他Shell,则可以放在${HOME}/.profile或同等功能中):
function AddUser18() { USER="${1}"; FILE="${2}"; sed -i~ '18s/=\s*{\?\s*\(".*"\)\s*}\?\s*/= {\1, "'"${USER}"'"}/' "${FILE}"; }

function DelUser18() { USER="${1}"; FILE="${2}"; sed -i~ '18s/=\s*{\s*\("[^"]*"\)\s*,\s*\("'"${USER}"'"\)\s*}/= \1/; 18s/=\s*{\s*\("[^"]*"\)\(.*\)\(\s*,\s*"'"${USER}"'"\)\(.*\)\s*}/= { \1\2\4 }/' "${FILE}"; }

我在sed中添加了-i~开关,以修改文件到位并制作带有'~'后缀的预置版本的备份。
您可以通过以下方式简单地使用这些功能:
source ~/.bashrc  # only if you are using the same shell where you modify .bashrc
AddUser18 user3 "path/to/the/file"  # to add a new user
DelUser18 user3 "path/to/the/file"  # to remove it (or another)

如果要修改的文件始终相同,则还可以在函数中对路径进行硬编码(因此,两个函数中的FILE均为FILE="path/to/the/file")。

09-30 23:53