Powershell 解析空格分隔字段
我正在尝试编写一个脚本,其工作原理如下: 我的输入是一个包含8行8列的文本文件,其中填充了值Powershell 解析空格分隔字段,powershell,split,type-conversion,Powershell,Split,Type Conversion,我正在尝试编写一个脚本,其工作原理如下: 我的输入是一个包含8行8列的文本文件,其中填充了值0或1,每个值用一个空格字符分隔列 我需要检查每行的第4个数字,如果是0,则输出false,如果是1,则输出true 目前我的代码如下所示: param($fname) $rows = (Get-Content $fname) for ($i=0;$i -lt $rows.Length;$i++) { if ($rows[$i][6] -eq 1) { Write-Host "true"
0
或1
,每个值用一个空格字符分隔列
我需要检查每行的第4个数字,如果是0
,则输出false
,如果是1
,则输出true
目前我的代码如下所示:
param($fname)
$rows = (Get-Content $fname)
for ($i=0;$i -lt $rows.Length;$i++)
{
if ($rows[$i][6] -eq 1)
{
Write-Host "true"
}
if ($rows[$i][6] -ne 1)
{
Write-Host "false"
}
}
所以我使用了[$I][6]
,因为我得到了第四个数字,占了充当分隔符的空格的数量
我检查并认为它是完美的,但不知怎的,它对每一行都说false
,但当我写主机时$rows[0][6]
它是1
tl;dr
# Create sample input file, with values of interest in 4th field
# (0-based field index 3).
@'
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
'@ > file
foreach ($line in (Get-Content file)) {
$fields = -split $line
if ($fields[3] -eq '1') {
"true"
} else {
"false"
}
}
收益率:
false
true
<> P>原始代码中有很多细微之处,但上面的代码:
- 借助一元
-split
运算符,通过将每个输入行拆分为空格分隔的字段(无论字段长度如何),提供了一种更类似于awk的方法
- 下标(索引)可以基于字段索引而不是字符位置
-split…
返回的所有字段都是字符串,因此可以与字符串literal'1'
进行比较,但是,通常情况下,PowerShell会为您执行许多幕后转换魔术:使用上面的代码-与您自己的代码不同-使用1
也会奏效
至于你的方法失败的原因:
- 在PowerShell中对字符串值进行索引(使用带下标的下标)是一种特殊情况:它隐式地将字符串视为字符数组,并使用单个索引(如
6
)返回一个[char]
实例
- 表达式的LHS(左侧)包含一个二进制运算符,例如
-eq
,它决定了在应用运算符之前,如有必要,RHS(右侧)将被强制为哪种类型:
([char]“1”)-eq 1#$错误
- 将RHS
1
的(隐含的)[int]
类型强制为LHS类型[char]
会产生Unicode码点U+0001
,即控制字符,而不是“ASCII”数字“1
”,这就是比较失败的原因
- @佩瑟拉尔(在对问题的评论中)提出了有用但隐晦的建议,即使用
'1'[0]
而不是1
,因为'1'[0]
作为[char]
实例返回1
,但该解决方案不能推广到多字符字段值
'1'-eq 1#$true;与以下内容相同:([string]1)-eq 1或([string]1)-eq'1'
- 将整数
1
转换为字符串实际上与'1'
相同
此脚本使用矩阵文件中的正确值填充真正的2d数组,但输出不适合
$Array = New-Object "bool[,]" 8,8
[int]$i=0 ; [int]$j=0
get-content $fname|foreach{ foreach ($b in ($_ -split(' '))) {
"{0},{1}={2}" -f $i,$j,($b -eq 0)
$Array[$i,$j] = ($b -eq 0)
$j++}
$j=0; $i++}
1
->'1'[0]
您正在将整数与字符进行比较。尝试运行$rows[$i][6]。GetType()
以查看PS用于数据的类型。您还可以删除最后一个if
,并将其更改为else
,因为如果它不是1,则为false。