我有一个文件 “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"
)。