我有以下属性键
connection.party= 0.0.0.0
remote.app.328.port= 5432
remote.server.url="https://someurl.com?q=78.78"
remote.conncetion.7="basic"
remote.52.base= "local"
level1.34access23="true"
88.location.code=24
location.234.code.52=24
我需要将此转换为以下内容
connection.party= 0.0.0.0
remote.app."328".port= 5432
remote.server.url="https://someurl.com?q=78.78"
remote.conncetion."7"="basic"
remote."52".base= "local"
level1.34access23="true"
"88".location.code=24
location."234".code."52"=24
嵌套的属性键中的所有数字都需要有双引号,这些数字具有pre或post或两者都具有点符号。不应更新键中与文本连接的数字。(level1.34access23=“true”=> no change)无法更新值。
我试过使用following,但它会给所有内容添加双引号。
sed -E 's/^([^=]+)\.([0-9]+)/\1."\2"/' input.properties
有人能帮帮我吗?
8条答案
按热度按时间ep6jt1vc1#
使用您显示的示例,请尝试以下在GNU
awk
中编写和测试的awk
代码。jrcvhitl2#
请尝试以下操作:
^([^=]+\.)?
匹配零个或一个除等号后跟点以外的任何字符序列。zero
的情况将匹配前导数字,例如88
。(\.|=)
匹配后面的点或等号。[编辑]
如果
perl
恰好是您的选择,那么:这在密钥中包含多个数字的情况下将起作用。
(^|\.)
匹配字符串的开头或一个点,匹配的子字符串被$1
引用为反向引用(就像\1
在sed中所做的那样)。(\d+)
匹配一个数字。(?=\.|=)
是一个正的前瞻,它匹配一个点或等号,而不增加正则表达式的搜索位置。(?=.*=)
是一个正的前瞻,它匹配后跟等号的任何字符序列。它确保替换仅发生在密钥内。g
选项支持多个替换。nzkunb0c3#
您的正则表达式显然也不需要在数字后面加一个点,并且与表达式开头的数字不匹配。
这里有一个简单的脚本,它用两边的点锚定数字,只要等号前还有未加引号的数字,就继续替换。
更详细地说
的标签
,这确保了只要还有需要引用的数字,我们就可以继续下去。
如果您在运行此脚本时遇到问题,请尝试将整个脚本放在单引号中:
正如您所看到的,
sed
几乎是一种只写语言。下面是一个简单的Awk脚本,它实现了相同的逻辑。这也有些浓缩,但并不难理解(如果您认为它太晦涩,Awk可以更容易地用手写写出内容)。
FS
和输出字段分隔符OFS
设置为等号。这会导致
$1
包含第一个等号之前的所有内容,而$2
、$3
等包含后续的等号分隔字段。然后,对于每个输入行
$1
(即第一个等号之前的所有内容)上的点到数组a
中。数组的长度为n
。f
,我们将在其中累积$1
的替换值。a
中的字段,即从1到n
:f
。f
不为空,则在f
的值后面追加一个点;否则,只保留一个空字符串,连接...这使用了三级运算符
(expression ? value : othervalue)
,如果expression
为真,则产生value
,否则产生othervalue
。因此,换句话说,如果f
非空,则产生f
的当前值和文字点"."
的串联;否则,生成空字符串。a[i]
,带或不带双引号,这取决于它是否完全是数值。f
将包含$1
的前一个值,但a
中的所有全数字字段都用双引号括起来。将其分配回$1
。右大括号终止了我们对每一行输入所执行的操作,而‘1’只是一个简单的习惯用法,它会导致Awk打印每一行。
(In更详细地说,值
1
被应用为一个条件,该条件始终为真,没有动作,这意味着默认动作,即打印当前输入记录。5q4ezhmt4#
如果你对python没问题
bxpogfeg5#
使用GNU awk for
gensub()
:或者使用任何awk:
ippsafx76#
我的两分钱:
第一个
sed
将一个属性及其值拆分为两行。第二个字符串在第一行(属性名)中用
"
字符包围数字,并连接值(来自第二行)。如果多行上有值,则行为将不是预期的行为:命令行必须在同一唯一行中找到属性及其值。
ogsagwnx7#
无需捕获组
cnwbcb6i8#