我试
$obj = [System.IO.File]::ReadLines((Convert-Path -LiteralPath names.json)) | ConvertFrom-Json
$keys = @()
foreach ($key in $obj.GetEnumerator()) {
$keys += $key.Key
}
Write-Output $keys
字符串
但24小时后,它还没有完成。
我需要钥匙的名字
1.删除不相关的信息,使其更小
1.将其转换为csv(键名称是必需的,否则PS只使用第一个对象并忽略第一个对象中不存在的键)
JSON是这个的一个版本(尽管小了200 megs):https://kaikki.org/dictionary/All%20languages%20combined/by-pos-name/kaikki_dot_org-dictionary-all-by-pos-name.json
2条答案
按热度按时间rkkpypqq1#
您可以流式处理文件并处理每行,避免对大文件使用
Get-Content
,并最大限度地减少小文件调用的次数:字符串
这种方法使用.NET
ReadLines
方法来有效地流式传输文件并处理每一行。我终于下载完了你的大JSON文件。
型
这将给你一个给予每个JSON对象的注解列表。
反馈回复:
也许可以使用哈希表来存储唯一键,避免不必要地使用
ForEach-Object
,并使用完整路径进行文件访问:型
这段代码避免了使用
+=
增长数组,使用foreach循环而不是ForEach-Object
,并在.NET方法中使用文件路径之前解析文件路径。tvokkenx2#
您已经在使用最有效的方法(在PowerShell中)来解析基于行的 JSONL 输入文件**(请参阅底部部分的解释)。
看起来您只是在**寻找
ConvertFrom-Json
解析JSON文档所生成的[pscustomobject]
示例的 * 属性名 *。注意事项:
$someObj
表示一个 * 单个 * 对象,就像您基于代码使用$someObj = $obj[0]
得到的对象一样,假定$obj
包含一个(大)* 数组 * 对象;示例可视化使用来自linked file的$obj[0]
。字符串
发现对象的 immediate(顶级)属性**的最简单方法是通过内部
psobject
属性:型
使用
Get-Member
是另一个选项(主要用于 * 显示 * 输出):型
然而,考虑到存储在
$obj
中的[pscustomobject]
示例是对象 * 图 *,即每个示例都是 * 嵌套 *[pscustomobject]
s的层次结构,您可能会对发现属性名称的 * 层次结构 * 感兴趣,即对象 * 结构:Get-LeafProperty
函数,它将一个给定的[pscustomobject]
表示为一个 * 属性路径-值对的列表 *;例如,$someObj | Get-LeafProperty
产生如下内容:型
ConvertTo-Json
**,利用这样一个事实,即所得到的JSON表示 * 默认情况下打印得很漂亮 *(选择退出需要使用-Compress
):型
-Depth
参数,该参数具有足够多的序列化级别,以避免截断(默认深度仅为2
;有关详细信息,请参阅this post)。Format-Custom
**:型
Format-*
小工具一样,输出仅用于 * 显示 *,不适合 * 编程 * 处理(参见this answer)。Format-Custom
的默认深度是5
,所以在这种情况下不需要-Depth
参数。$FormatEnumerationLimit
首选项变量,以确保属性值中 collection(数组)的所有元素都是可视化的;默认情况下,只有 4 元素,省略的元素表示为…
。示例
Format-Custom
输出(删节):型
基于上面发现的属性,下面是一个calculated property的例子,它从输入对象创建CSV数据:
型
高效处理JSONL文件:
suchislife找到了一个合适的术语来描述JSON输入数据的line-based 格式:JSONL (JSON Lines format);也就是说,输入文件的*每一行 * 都是一个 self-contained JSON文档(这意味着文件 * 作为一个整体 * 不是 * 有效的JSON,因为缺少一个整体的封闭对象或数组)。
ConvertFrom-Json
有内置的语法支持此类输入:因此,正如你的问题所示,
(
[System.IO.File]::ReadLines((Convert-Path -LiteralPath names.json)) | ConvertFrom-Json
):*您可以将JSONL文件的行一行一行地 * 直接 * 传输到
ConvertFrom-Json
。ForEach-Object
调用要高效得多,在ForEach-Object
调用中,ConvertFrom-Json
每一行调用 * 一次 *。ConvertFrom-Json
在[pscustomobject]
* 输出 * 对象 * 可用时 *(即,在解析给定输入行之后)对其进行流传输。[System.IO.File]::ReadLines()
是(目前)需要*.Convert-Path
用于确保传递 * 完整 * 路径,因为.NET的工作目录通常与PowerShell的工作目录 * 不同 *(参见this answer)。Get-Content
(没有-Raw
)也可以工作,但不幸的是,它要慢得多,因为每一行读取都用ETS (Extended Type System)属性进行了修饰。-NoExtendedMember
开关引入这种昂贵的装饰的 * 选择退出 * 已经亮起绿灯,但还没有人加强实现它(截至PowerShell 7.3.10,截至本文撰写时)。[1]但是,如果集合值属性包含 * 不同类型的示例 *,则可能必须显示 * 所有 * 元素。