【问题标题】:Get first two items positionally from Import-CSV row从 Import-CSV 行中按位置获取前两项
【发布时间】:2017-08-21 19:15:25
【问题描述】:

我有一系列文件随着时间的推移更改了一些标题命名和列计数。但是,文件始终将第一列作为开始日期,将第二列作为结束日期。

我只想获取这两列,但名称随着时间的推移而改变。 我试过的是这样的:

 $FileContents=Import-CSV -Path "$InputFilePath" 
 foreach ($line in $FileContents)
 {
     $StartDate=$line[0]
     $EndDate=$line[1]
 }

...但是 $FileContents 是(我相信)一个类型(对象?)的数组,我不确定如何在 PowerShell 中进行位置访问。任何帮助将不胜感激。

编辑:文件从逗号分隔符切换到管道分隔符,并且有 1000 多个文件可以使用,所以我使用 Import-CSV,因为它可以隐式读取任何一种格式。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您可以使用-Header 参数为csv 的第一个列提供您想要的标题名称。然后,您将跳过具有旧标题的第一行。

    $FileContents = Import-CSV -Path "$InputFilePath" -Header "StartDate","EndDate" | Select-Object "StartDate","EndDate" -Skip 1
    
    foreach ($line in $FileContents) {
        $StartDate = $line.StartDate
        $EndDate = $line.EndDate
    }
    

    这是一个例子:

    Example.csv
    
    a,b,c
    1,2,3
    4,5,6
    
    Import-CSV -Path Example.csv -Header "StartDate","EndDate" | Select-Object "StartDate","EndDate" -Skip 1
    
    StartDate EndDate
    --------- -------
    1         2
    4         5
    

    【讨论】:

    • 我比我更喜欢你的回答,因此我赞成。 Header 参数也可用于Convertfrom-Csv竖起大拇指
    • GJ,但不是必须的 'Select-Object "StartDate","EndDate" -Skip 1',因为 'Select -skip 1' 就足够了
    【解决方案2】:

    如果您使用Import-Csv,PowerShell 确实会为您创建一个对象。 “列”是调用属性。您可以使用Select-Object 选择属性。您必须命名要选择的属性。由于您事先不知道属性名称,因此您可以使用Get-Member 获取名称。前两个属性应与 CSV 中的前两列匹配。

    使用以下示例代码并将其应用于您的脚本:

    $csv = @'
    1,2,3,4,5
    a,b,c,d,e
    g,h,i,j,k
    '@
    
    $csv = $csv | ConvertFrom-Csv
    $properties = $csv | Get-Member -MemberType NoteProperty | Select-Object -First 2 -ExpandProperty Name
    $csv | Select-Object -Property $properties
    

    【讨论】:

    • 您应该展示如何在循环中获取值。例如foreach ($line in $csv) {$startdate = $line.($properties[0])}
    【解决方案3】:

    这个怎么样:

    $FileContents=get-content -Path "$InputFilePath" 
    
    for ($i=0;$i -lt $FileContents.count;$i++){
        $textrow = ($FileContents[$i]).split(",")
        $StartDate=$textrow[0]
        $EndDate=$textrow[1]
    
        #do what you want with the variables
        write-host $startdate
        write-host $EndDate
    }
    

    等待您引用 csv 文件....

    【讨论】:

    • 这种方法的假设是分隔符在数据中,否则拆分和额外引号会出现问题。您还需要跳过第一行,所以 $i=0 -> $i=1 否则旧标题将成为您数据中的对象。
    • 这行得通。我将“StartDateColumn”、“EndDateColumn”作为带有“foreach($FileContents 中的$line)”的标题。使用 $line.StartDateColumn 得到了所需的结果。谢谢。
    【解决方案4】:

    使用 foreach(%=foreach 的别名)和拆分的其他解决方案:

    Get-Content "example.csv" | select -skip 1 | %{$row=$_ -split ',', 3; [pscustomobject]@{NewCol1=$row[0];NewCol2=$row[1]}} 
    

    【讨论】:

      【解决方案5】:

      您也可以像这样在选择中构建谓词:

      Get-Content "example.csv" | select @{N="Newcol1";E={($_ -split ',', 3)[0]}}, @{N="Newcol2";E={($_ -split ',', 3)[1]}} -skip 1
      

      【讨论】:

        【解决方案6】:

        使用转换字符串

        Get-Content "example.csv" | ConvertFrom-Csv -Delimiter ',' -Header col1, col2 | select -skip 1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多