【问题标题】:Import/Export .csv file导入/导出 .csv 文件
【发布时间】:2018-12-01 06:02:55
【问题描述】:

我有 100 个日期的 testDates.csv

日期 2017 年 1 月 10 日 2018 年 6 月 10 日 9/10/42 ...

我制作了一个脚本,根据这些日期制作示例密码:

$file = Import-Csv -Path U:\Desktop\testDates.csv

foreach ($line in $file) {
    $fullDate = $line.date
    $year = Get-Date $fullDate -Format "yy"
    $currentDate = Get-Date $fullDate -Format "MM-dd"

    # Determining season
    if ($currentDate -ge (Get-Date 01-01) -and $currentDate -lt (Get-Date 03-01)) {
        $season = "Winter"
    } elseif ($currentDate -ge (Get-Date 03-01) -and $currentDate -le (Get-Date 05-31)) {
        $season = "Spring"
    } elseif ($currentDate -ge (Get-Date 06-01) -and $currentDate -le (Get-Date 08-31)) {
        $season = "Summer"
    } elseif ($currentDate -ge (Get-Date 09-01) -and $currentDate -le (Get-Date 11-30)) {
        $season = "Fall"
    } elseif ($currentDate -ge (Get-Date 12-01) -and $currentDate -le (Get-Date 12-31)) {
        $season = "Winter"
    } else {
        $season = "ClearyAnIntern"
    }

    # Creating password
    $SamplePassword = $season + $year
}

我想将创建的密码导出回新列中的原始 .csv。所以在“日期”旁边有一列“密码”,看看我的脚本是否正常工作。示例:

日期密码 1/10/17 Winter17 2018 年 6 月 10 日夏季 18 9/10/42 秋季 42 ……

我知道它涉及Export-Csv,但我不知道如何特别针对每一行进行管道传输。我一直在查看大量不同的线程和 MS 帮助中心,了解如何使用不同的参数,例如 -Append 等等,但我所看到和尝试的一切并不完全是我正在处理和从这些例子中推断出我目前的补救知识范围之外。我开始相信这可能涉及嵌套的 foreach 循环。

【问题讨论】:

  • 是的,我正在研究北方气象而不是天文季节范围。夏天快乐。

标签: powershell csv powershell-3.0


【解决方案1】:

Export-Csv 需要一个对象列表作为输入,所以这就是您需要首先创建的内容。

foreach ($line in $file) {
    ...
    [PSCustomObject]@{
        'date'     = $fullDate
        'password' = $SamplePassword
    }
}

接下来,foreach 循环无法写入管道,因此您需要在循环内追加到输出文件:

foreach ($line in $file) {
    ...
    [PSCustomObject]@{
        'date'     = $fullDate
        'password' = $SamplePassword
    } | Export-Csv 'output.csv' -NoType -Append
}

或将输出收集到一个变量中,然后将其导出:

$list = foreach ($line in $file) {
    ...
    [PSCustomObject]@{
        'date'     = $fullDate
        'password' = $SamplePassword
    }
}

$list | Export-Csv 'output.csv' -NoType

否则你需要用ForEach-Object循环替换foreach循环:

Import-Csv 'U:\Desktop\testDates.csv' | ForEach-Object {
    $fullDate = $_.date
    ...
    [PSCustomObject]@{
        'date'     = $fullDate
        'password' = $SamplePassword
    }
} | Export-Csv 'output.csv' -NoType

【讨论】:

    【解决方案2】:
    Import-Csv C:\path\input.csv | ForEach-Object {
       $seasons = [Char[]]'wwsssmmmfffw' # seasons map
    }{ # walk around CSV lines
       [PSCustomObject]@{
          Date = $_.date # first and second columns of future CSV
          Password = "$(switch ($seasons[([DateTime]$_.date).Month - 1]) {
             'w' {'Winter'} 's' {'Spring'} 'm' {'Summer'} 'f' {'Fall'}
          })$(Get-Date $_.date -Format yy)"
       }
    } | Export-Csv C:\path\out.csv # export result
    

    【讨论】:

    • 喜欢这种方法。我发现要得到正确的结果必须减去 1,因为季节图从 0 开始计数:Password = "$(switch ($seasons[(get-date $_.date).Month -1]) ..
    • @Itchydon 谢谢你的警惕。已更新。
    • 很高兴 - 我还发现我需要将其更改为 get-date 否则以这种方式从 [DateTime] 中减去 1 会给我一个错误
    • 难以置信!我希望我能理解它是如何工作的,但我无法理解它是如何计算季节的。有没有推荐的进一步阅读来教育自己?
    • @Ryan 没有任何黑魔法,只有 PS 代码。一年中的每个季节都由月份名称或数字决定,每个季节都有三个月,对吗?这是基本逻辑,不再赘述。而且我不知道为什么确定一年中的一个季节应该是复杂的。进一步阅读?总有一些东西要学。
    【解决方案3】:

    您可以将Calculated properties 与for 循环结合使用来执行此操作。下图也一样——

    #Importing csv dates file
    $file = Import-Csv -Path U:\Desktop\testDates.csv
    
    #Declaring the variable to store passwords
    $SamplePassword = @()
    
    #loop
    foreach ($line in $file)
    {
        #Variable declarations
        $fullDate = $line.date
        $year = get-date $fullDate -Format "yy"
        $currentDate = get-date $fullDate -Format "MM-dd"
    
        #Determining season
        if ($currentDate -ge (get-date 01-01) -and $currentDate -lt (get-date 03-01))
            {$season = "Winter"}
        elseif ($currentDate -ge (get-date 03-01) -and $currentDate -le (get-date 05-31))
            {$season = "Spring"}
        elseif ($currentDate -ge (get-date 06-01) -and $currentDate -le (get-date 08-31))
            {$season = "Summer"}
        elseif ($currentDate -ge (get-date 09-01) -and $currentDate -le (get-date 11-30))
            {$season = "Fall"}
        elseif ($currentDate -ge (get-date 12-01) -and $currentDate -le (get-date 12-31))
            {$season = "Winter"}
        else{
        $season = "ClearyAnIntern"
        }
    
        #Creating password
        $SamplePassword += $season + $year
    }
    

    完成上述步骤后,您的$SamplePassword 将包含所有密码。使用带有 for 循环的计算属性,如下所示 -

    #Declaring a new variable to store the results
    $NewCsv = @()
    $Originalcsv = Import-Csv -path U:\Desktop\testDates.csv
    for($i = 0; $i -lt $Originalcsv.Length; $i++)
    {
        $NewCsv += $Originalcsv[$i] | Select-Object *, @{Name='Password';Expression={$SamplePassword[$i]}}
    }
    
    $NewCsv | Export-Csv U:\Desktop\NewtestDatesWithPasswords.csv -NoTypeInformation
    

    【讨论】:

      【解决方案4】:

      我只猜你 csv 文件中的日期格式为 M/d/yy ? 从 csv 导入变量类型始终是字符串,因为我自己的语言环境偏离了我必须定义不同的文化来转换。

      使用您其他问题中我的function Get-Season 的修改版本。

      ## Q:\Test\2018\06\21\SO_50976425.ps1
      ## define function first
      Function Get-Season([datetime]$Date){
          If (!$Date) {$Date = Get-Date} #If date was not provided, assume today.
          # The dates are obviously not exactly accurate and are best guesses
          $Spring = Get-Date -Day 20 -Month 03 -Year $Date.Year
          $Summer = Get-Date -Day 21 -Month 06 -Year $Date.Year
          $Autumn = Get-Date -Day 22 -Month 09 -Year $Date.Year
          $Winter = Get-Date -Day 21 -Month 12 -Year $Date.Year
          $Season = switch($Date) {
              {($_ -lt $Spring)}  {"Winter";Break}
              {($_ -lt $Summer)}  {"Spring";Break}
              {($_ -lt $Autumn)}  {"Summer";Break}
              {($_ -lt $Winter)}  {"Autumn";Break}
              {($_ -ge $Winter)}  {"Winter"}
          }
          "{0}{1}" -f $Season,$Date.ToString('yy')
      }
      
      #Importing csv dates file
      $file = Import-Csv -Path '.\testDates.csv'
      
      # get CultureInfo
      $CIUS = New-Object System.Globalization.CultureInfo("en-US")
      
      # process $file and create a new PSCustomObject
      $DatePassw = foreach ($line in $file){
          $fullDate = [datetime]::ParseExact($line.date,"M/d/yy",$CIUS)
          [PsCustomObject]@{
              date     = $line.date
              password = (Get-Season $fulldate)
          }
      }
      $DatePassw | ft
      $DatePassw | Export-Csv '.\testdatepassw.csv' -NoTypeInformation
      

      样本输出:

      > .\SO_50976425.ps1
      
      date    password
      ----    --------
      1/10/17 Winter17
      6/10/18 Spring18
      9/10/42 Summer42
      
      > gc .\testdatepassw.csv
      "date","password"
      "1/10/17","Winter17"
      "6/10/18","Spring18"
      "9/10/42","Summer42"
      

      【讨论】:

      • 如果您更喜欢Fall 而不是Autumn,只需在函数中进行交换即可。顺便说一句,9 月 10 日仍然是夏天(在原始定义中),但您也可以将其更改为季度定义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 2011-04-16
      • 2016-01-03
      • 1970-01-01
      • 2021-05-29
      • 2014-05-19
      • 1970-01-01
      相关资源
      最近更新 更多