如何在KQL中移除数组内包含指定文件类型的元素?
问题描述
日志源格式如下:
//file1.png是文件名,括号内为文件大小(字节)。 // 每个条目以分号分隔。 file1.png (445b); file2.pdf (2345b); file3.jpg (343b); file4.docx (3243b);
我原本用以下KQL语句,通过extract_all将条目拆分为嵌套列表,子列表索引0为文件名、1为扩展名、2为字节大小:
datatable (item:string ) [ 'file1.png (445b); file2.pdf (2345b); file3.jpg (343b); file4.docx (3243b);', 'file1.src (3243b); file2.ps2 (24b); file3.jpg (300b); file4.jpg (326b);' ] | extend list = extract_all(@'([^<>:"\/\\|\?\*;]+)\.([a-zA-z0-9]+) \((\d+)b\);', item)
输出格式类似:
[["file1", "png", "445"], ["file2", "pdf", "2345"], ["file3", "jpg", "343"], ["file4", "docx", "3243"]]
现在需要移除嵌套列表中包含特定扩展名(比如png)的子列表,但KQL没有迭代功能,之前尝试用含负前瞻的正则排除匹配条目:
(?:^|; =?)([^<>:"\/\\|\?\*;]+)\.(?!jpg\b|png\b)\w+ \((\d+)b\))(?=;|$)
但KQL不支持负前瞻,请问该如何实现?
解决方案
可以通过mv-expand将嵌套列表展开为单独行,过滤掉不需要的扩展名后,再用make_list重新聚合为嵌套列表,具体代码如下:
datatable (item:string ) [ 'file1.png (445b); file2.pdf (2345b); file3.jpg (343b); file4.docx (3243b);', 'file1.src (3243b); file2.ps2 (24b); file3.jpg (300b); file4.jpg (326b);' ] | extend list = extract_all(@'([^<>:"\/\\|\?\*;]+)\.([a-zA-z0-9]+) \((\d+)b\);', item) // 展开列表为单独行,保留原item的标识 | mv-expand list to typeof(dynamic) // 过滤掉扩展名是png或jpg的条目(可根据需求调整) | where list[1] !in ("png", "jpg") // 按原item分组,重新聚合为嵌套列表 | summarize filtered_list = make_list(list) by item
说明
mv-expand list to typeof(dynamic):将每个嵌套列表拆分为独立的行,每一行对应一个子列表元素,同时保留原始的item字段用于后续分组。where list[1] !in ("png", "jpg"):根据子列表的索引1(扩展名)过滤掉不需要的条目,可根据需求修改目标扩展名。summarize filtered_list = make_list(list) by item:按原始的item字段分组,将过滤后的子列表重新聚合为嵌套列表,得到最终结果。
内容的提问来源于stack exchange,提问作者Joseph Mccallum-Nattrass
相关产品推荐
相关产品推荐

