我正在尝试在bash脚本中对文件执行以下操作:
之前:
{
"main": "3.3.0",
"archive":[
"3.2.2"
]
}
之后:
{
"main": "3.3.1",
"archive":[
"3.3.0",
"3.2.2"
]
}
使用此perl一个衬垫:
perl -pi -e "s/\"main\"\: \"(.*?)(\".*)\[/\"main\": \"${version}\2\[\n\t\t\"\1\",/s" "$json"
$version
保留新版本号,而$json
是文件的路径。
似乎perl不匹配,我也不明白为什么。删除\[
确实可以,但是我看不出该文字有什么问题。
答案 0 :(得分:3)
假设您可以修复JSON(不允许使用逗号结尾),建议您使用模块和脚本进行处理。
一个带有JSON的示例,该示例按要求包裹在“一个”内衬中
perl -MPath::Tiny -MJSON -0777 -wnE'
my $hr = decode_json $_;
unshift @{$hr->{archive}}, $hr->{main};
$hr->{main} =~ s/[0-9]+\.[0-9]+.\K([0-9]+)/$1+1/e;
path("new_".$ARGV)->spew(encode_json $hr)'
' data.json
非常方便的Path::Tiny用于轻松转储JSON输出。我通过在输入文件名前面加上new_
(在$ARGV variable中)来制作输出文件名,并进行适当调整。
如果由于某种原因安装模块有问题,您可以直接打印JSON编码的字符串并重定向输出
perl -MJSON -0777 -wnE'
my $hr = decode_json $_;
unshift @{$hr->{archive}}, $hr->{main};
$hr->{main} =~ s/[0-9]+\.[0-9]+.\K([0-9]+)/$1+1/e;
say encode_json $hr
' data.json > new_data.json
它们产生带有{"archive":["3.3.0","3.2.2"],"main":"3.3.1"}
使用-0777
command switch,将整个文件“提取”为标量($_
),然后-M...
加载给定的模块。然后,我们使用decode_json
(默认情况下,JSON
在其功能接口中导出)来获取包含数据的hashref。
然后使用unshift将main
的当前值添加到archive
中arrayref的开头,然后使用正则表达式通过提高其发行版/补丁号来进行更改
最后,encode_json
也导出到JSON
的功能接口中,用于对hashref进行JSON编码,然后将其与Path::Tiny
一起转储到文件或STDOUT中以用于重定向。
在Grinnz的评论提示下,按顺序对现有JSON模块的数量进行了说明。
上面链接的JSON将加载JSON::XS模块,如果未安装该模块,则它将退回到兼容的纯Perl模块JSON::PP。我建议使用XS模块,该模块速度更快且已被广泛使用。
另一个选择是Cpanel::JSON::XS,它是JSON::XS
分支,带有错误跟踪器和bug fixes的列表。我很高兴地使用了两者,没有任何问题。
要按顺序依次尝试Cpanel::
然后::XS
然后::PP
,并且在加载方式方面对JSON
进行了一些改进,请使用JSON::MaybeXS。
请注意,这些都不是核心。
答案 1 :(得分:1)
(现在我的问题已经重新打开,我可以发布答案了。)
假设您修复了数据,使其成为有效的JSON(请注意无效的结尾逗号),这是一个简单的jq单行代码:
$ jq "{main: \"$version\", archive: [ .main, .archive[] ]}" "$json" > new.json
$ mv -f new.json "$json"
就像HTML和XML一样,使用正则表达式尝试操作JSON是一个错误。使用更合适的工具。
答案 2 :(得分:1)
使用jq
将main
版本号移动到数组archive
并递增main
版本的最后一位:
jq '.archive += [.main] |
.main |= (split(".") | .[-1] |= (tonumber+1|tostring) | join("."))' file
运算符+=
向数组archive
添加新值。
运算符|=
为main
分配一个新值。分割后的字符串的最后一个元素加1,然后重新组装。