string 用于存储字符串的 PowerShell 数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21884828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:13:48  来源:igfitidea点击:

PowerShell array to store strings

stringpowershellarrays

提问by Grady D

I have a list of files that I am breaking up into parts. That works, but I want to be able to reference each part individually. The issue is with my array not wanting/being able to take in a string. The file naming format is custID_invID_prodID or custID_invID_prodID_Boolvalue.

我有一个文件列表,我将这些文件分成几部分。这有效,但我希望能够单独引用每个部分。问题在于我的阵列不想/无法接收字符串。文件命名格式为 custID_invID_prodID 或 custID_invID_prodID_Boolvalue。

$files = Get-ChildItem test *.txt
[string]$custId = $files.Count
[string]$invID = $files.Count
[string]$prodID = $files.Count
[int]$Boolvalue = $files.Count
foreach($file in (Get-ChildItem test *.txt)) {
    for($i = 0; $i -le $files.Count; $i++){
        $custId[$i], $invID[$i], $prodID[$i], $Boolvalue[$i] = $file.BaseName -split "_"
        Write-Host $custId, $invID, $prodID, $Boolvalue
    }
}

The error message I am seeing is:

我看到的错误消息是:

Unable to index into an object of type System.String.

无法索引到 System.String 类型的对象。

How can I do this?

我怎样才能做到这一点?

采纳答案by Robert Westerlund

I'd suggest working with objects instead of a lot of string arrays. I have an example below in which I have replaced the file listing, since I don't have the file structure in place, with an ordinary array. Just remove that array declaration and put in your Get-ChildItemcall and it should work just fine.

我建议使用对象而不是大量的字符串数组。我在下面有一个示例,其中我替换了文件列表,因为我没有使用普通数组的文件结构。只需删除该数组声明并放入您的Get-ChildItem调用中,它应该可以正常工作。

function ConvertTo-MyTypeOfItem
{
    PARAM (
        [ValidatePattern("([^_]+_){3}[^_]+")]
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$StringToParse
    )

    PROCESS {
        $custId, $invId, $prodId, [int]$value = $StringToParse -split "_"
        $myObject = New-Object PSObject -Property @{
            CustomerID = $custId;
            InvoiceID = $invId;
            ProductID = $prodId;
            Value = $value
        }
        Write-Output $myObject
    }
}

# In the test scenario I have replaced getting the list of files
# with an array of names. Just uncomment the first and second lines 
# following this comment and remove the other $baseNames setter, to
# get the $baseNames from the file listing

#$files = Get-ChildItem test *.txt
#$baseNames = $files.BaseName
$baseNames = @(
    "cust1_inv1_prod1_1";
    "cust2_inv2_prod2_2";
    "cust3_inv3_prod3_3";
    "cust4_inv4_prod4_4";
)

$myObjectArray = $baseNames | ConvertTo-MyTypeOfItem 

$myObjectArray

The above function will return objects with the CustomerID, InvoiceID, ProductIDand Valueproperties. In the sample above, the function is called and the returned array value is set to the $myObjectArray/code> variable. When output in the console it will give the following output:

上述函数将返回对象与CustomerIDInvoiceIDProductIDValue属性。在上面的示例中,调用了该函数并将返回的数组值设置为$myObjectArray/code> variable. When output in the console it will give the following output:

InvoiceID                CustomerID               ProductID                                  Value
---------                ----------               ---------                                  -----
inv1                     cust1                    prod1                                          1
inv2                     cust2                    prod2                                          2
inv3                     cust3                    prod3                                          3
inv4                     cust4                    prod4                                          4

回答by Adam Luniewski

Seems to me that you're doing it the hard way. Why 4 arrays for every "field" of a file? It's better to create array of arrays - first index would indicate a file, and second a field in file:

在我看来,你这样做很困难。为什么文件的每个“字段”有 4 个数组?最好创建数组数组 - 第一个索引表示一个文件,第二个索引表示文件中的一个字段:

$files = Get-ChildItem test *.txt

$arrFiles = @(,@());
foreach($file in $files ) {
    $arrFile = $file.BaseName -split "_"
    $arrFiles += ,$arrFile;
}
Write-Host "listing all parts from file 1:"
foreach ($part in $arrFiles[1]) {
    Write-Host $part
}
Write-Host "listing part 0 from all files":
for ($i=0; $i -lt $arrFiles.Count ; $i++) {
    Write-Host $arrFiles[$i][0];
}

回答by arco444

Because you're trying to index into an object of type System.String! You set all your variables as strings to start with and then try to assign to an index, which I presume would attempt to assign a string to the character position at the index you provide.

因为您正在尝试索引 System.String 类型的对象!您将所有变量设置为字符串开始,然后尝试分配给一个索引,我认为它会尝试将一个字符串分配给您提供的索引处的字符位置。

This is untested but should be in the right direction.

这是未经测试的,但应该是正确的方向。

$custIdArr = @()
$invIDArr = @()
$prodIDArr = @()
$BoolvalueArr = @()
foreach($file in (Get-ChildItem test*.txt)) {
    $split = $file.BaseName -split "_"
    $custId = $split[0];  $custIdArr += $custId
    $invID = $split[1];  $invIDArr += $invId
    $prodID = $split[2];  $prodIDArr += $prodID
    $boolValue = $split[3];  $boolValueArr += $boolValue
    Write-Host $custId, $invID, $prodID, $Boolvalue
}

Create a set of empty arrays, loop through your directory, split the filename for each file, append the results of the split into the relevant array.

创建一组空数组,遍历您的目录,拆分每个文件的文件名,将拆分的结果附加到相关数组中。

I'm assigning to $custId, $invID, $prodID, $Boolvaluefor the sake of clarity above, you may choose to directly add to the array from the $splitvar i.e. $invIDArr += $split[1]

$custId, $invID, $prodID, $Boolvalue为了上面清楚起见,我分配给,您可以选择直接从$splitvar ie添加到数组$invIDArr += $split[1]