我有一个 Json 格式的文件,如下所示:
{
"sources":[{
"field1":1000,
"field2":"winevent_log",
"field3":"winevent_log",
"field4":"os_security",
"field5":true,
"field6":false,
},{
"field1":1001,
"field2":"winperf_cpu",
"field3":"winperf_cpu",
"field4":"os_perf",
"field5":false,
"field6":false,
},{
"field1":1002,
"field2":"winperf_disk",
"field3":"winperf_disk",
"field4":"os_perf",
"field5":false,
"field6":false,
},{
"field1":1003,
"field2":"winperf_mem",
"field3":"winperf_mem",
"field4":"OS_perf",
"field5":false,
"field6":false,
}
}
我正在尝试根据分隔符将其拆分为不同的文件。我希望看到如下所示的 4 个不同的文件:
文件 1:
{
"field1":1000,
"field2":"winevent_log",
"field3":"winevent_log",
"field4":"os_security",
"field5":true,
"field6":false,
}
文件2:
{
"field1":1001,
"field2":"winperf_cpu",
"field3":"winperf_cpu",
"field4":"os_perf",
"field5":false,
"field6":false,
}
等等等等。
我尝试使用 csplit 和 awk 命令:
csplit input_file '/"id"/' '{*}'
awk '/,{/{n++}{print >"out" n ".json" }' input_file
但是我还没有得到我期望的 output_files,因为分隔符分布在多行上,并且从一行的中间开始。
有谁知道如何使用 awk 或 csplit 使得起始分隔符为“{换行符“field1””,而结束分隔符为“}”,
答案1
使用范围地址(如在 sed 中)并{
放回}
sprintf
awk '/field1/,/field6/ {if ($0 ~ /field1/) {i++;$0=sprintf(" {\n%s",$0)}; if ($0 ~ /field6/) {$0=sprintf("%s\n }",$0)}; print > ("file" i)}' input_file
有一些静态字符串,如果它们会改变,那么您可以用正则表达式替换。
答案2
假设您的情况下的分隔符是},{
,您可以使用ex
编辑器(Vim 的一部分)来拆分文件,例如:
ex +%j +'%s/},{/},\r{/g' +'g/./exe ".w! file".line(".").".txt"' -scq! -V1 file.txt
它将连接所有行 ( %j
),用新行 ( %s
) 替换内容( ),然后根据当前行号将每行写入单独的文件。缺点是您的组件部分在一行中,但您可以使用逗号将其再次拆分。有关更多详细信息,请查看:},{
\r
如何将每一行写入单独的文件?