我有以下由人类维护的 Java 属性文件。
# file.input = /very/old/name
# file.input = /old/name
file.input = /current/name
file.input.default = /default/name
other.file.input = /current/other/name
# Other comments
other.properties = must stay the same
我必须创建一个脚本来编辑此文件,而无需触及其他文件。因此我无法在配置文件中转储新属性。
人们经常会复制/粘贴一行并对其进行注释以供进一步使用。我的应用程序必须专门编辑配置文件,而不触及任何注释。
在这种特殊情况下,我想编辑该行file.input
以将值设置为,/new/name
而不触及任何注释行,也不触及任何其他属性(file.input.default
,other.file.input
)。我的脚本不会像人类通常那样保留当前行以用于历史目的。另外,我不知道设置为 key 的当前值file.input
。
我被困在哪里了?一开始。我不是 Bash 专家,除了按顺序调用命令以及有时使用一些 if 之外,我很少使用它。但仅此而已。
我可以perl
使用正则表达式,但 perl 显然没有安装在这个系统上。所以我依次转向sed
,但我没有得到任何结果:看来我只能将一个特定值替换为另一个值。我可以将其包装在文件的读取中,然后重写它,除了我可以更改的预期行之外。另外,我几乎无法处理我想要改变的房产前面人工添加的空间。
因此,如果您有其他选择,请分享,因为我开始变得疏远。
答案1
sed
使用(就地编辑)的 -i 选项。警告是用于分隔替换命令的字符不得出现在 NEW 字符串中。该示例使用 ':' 而不是 '/' 来分隔 ( s:old_string:new_string:
)
NEW=/new/name
sed -i 's:^[ \t]*file.input[ \t]*=\([ \t]*.*\)$:file.input = '${NEW}':' f
答案2
解决方案使用awk
:
$ awk -F'=' '$1 ~ /^[ \t]*file.input[ \t]*$/{$2="= /new/name"}{print}' config
# file.input = /very/old/name
# file.input = /old/name
file.input = /new/name
file.input.default = /default/name
other.file.input = /current/other/name
# Other comments
other.properties = must stay the same
然后你可以将其保存到新的配置文件中:
awk -F'=' '$1 ~ /^\s*file.input\s*$/{$2="= /new/name"}{print > "new_config"}' config
答案3
请注意,如果您需要在脚本中使用它来跨平台工作(也可以在 MacOSX 上工作),那么您需要使用完整-i
标志,提供备份文件扩展名:
NEW=/new/thing
sed -i.backup 's|\s*file.input\s*=.*$|file.input = '${NEW}'|' filename
## Then you can check exit code and remove the backup file if all is well
## rm filename.backup
否则,在 MacOSX 上您会收到类似“命令末尾有多余字符”的错误。