使用PowerShell读取TXT前两列BARCODE与LOCATION转对象遇阻求助
固定列宽文本转PowerShell对象的实现问题
需求描述
需要从指定路径的TXT文本中提取前两列BARCODE、LOCATION字段内容,转换为可操作的PowerShell自定义对象,当前在对象创建环节无法得到符合预期的结果。
参考文件格式
目标TXT文件为固定列宽存储的磁带信息,示例结构如下:
#BARCODE LOCATION LIBRARY STATUS COPY #------- -------- ------- ------ ---- #L40001L8 slot 41 DRP_TAPE_DRPLTO Full Primary_Global #L40002L8 slot 96 DRP_TAPE_DRPLTO Full Primary_Global #L40034L8 IEPort2 DRP_TAPE_DRPLTO Full Primary_Global
现有尝试代码
$object= @{} ForEach ($i in $(gc "C:\temp\tapes.txt")) { $object.BARCODE= ($i.ToString().Substring(0,8)) $object.LOCATION= ($i.ToString().Substring(0,19)) New-Object psobject -Property $object }
现有代码的核心错误
- 全程复用同一个全局哈希表存储属性,循环迭代时会不断修改同一个对象的属性值,最终生成的所有PS对象会共享最后一次循环的属性内容,无法逐行匹配数据
- 字段截取的索引位置完全错误:
BARCODE从0位开始截8位的逻辑符合列宽,但LOCATION同样从0位开始截19位,等于把BARCODE的内容重复截取给LOCATION字段,没有取到LOCATION列的实际值 - 未过滤无效行:文件中以
#开头的表头、分隔线行也会被当成数据行处理,生成无意义的空值、注释内容对象
可直接运行的实现方案
按照固定列宽的格式调整截取逻辑、修正对象创建的流程,代码如下:
Get-Content "C:\temp\tapes.txt" | # 过滤所有以#开头的表头、分隔线无效行 Where-Object { $_ -notmatch '^#' } | ForEach-Object { # 每轮循环生成独立的属性哈希表,避免多对象共享属性值 $properties = @{ BARCODE = $_.Substring(0, 8).Trim() # 按照实际列位置:BARCODE占0-7位,之后跳过填充空格,LOCATION从13位开始截取10位长度 LOCATION = $_.Substring(13, 10).Trim() } # 基于独立属性创建标准PS对象 New-Object psobject -Property $properties }
方案说明
- 截取后的
.Trim()方法用于清理列之间的填充空格,避免属性值附带多余空白字符 - 如果后续文件的列宽发生变动,只需要调整
Substring()的两个参数(起始位置、截取长度)即可,不需要修改整体逻辑 - 生成的PS对象支持直接调用
Export-Csv、Where-Object等PowerShell原生 cmdlet 做后续数据处理
内容的提问来源于stack exchange,提问作者user2637202
相关产品推荐
相关产品推荐

