Perl正则表达式一个内衬无法正常工作

时间:2018-10-19 13:28:33

标签: regex bash perl

我正在尝试在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不匹配,我也不明白为什么。删除\[确实可以,但是我看不出该文字有什么问题。

3 个答案:

答案 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。

然后使用unshiftmain的当前值添加到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)

使用jqmain版本号移动到数组archive并递增main版本的最后一位:

jq '.archive += [.main] |
    .main |= (split(".") | .[-1] |= (tonumber+1|tostring) | join("."))' file

运算符+=向数组archive添加新值。

运算符|=main分配一个新值。分割后的字符串的最后一个元素加1,然后重新组装。