正在更新导出的csv powershell的列值

正在更新导出的csv powershell的列值,powershell,csv,Powershell,Csv,我有以下代码,它工作正常。 虽然我现在需要修改一个特定列中的输出,所以我可以按此列正确排序 这是我的密码: $inputFile = "C:\Data\expPasswords\expPasswords.csv" $outputFile = "C:\Data\expPasswords\expPasswordsUp.csv" $result = Import-Csv $inputFile | Select-Object @{ Name = 'Account'; Expr

我有以下代码,它工作正常。 虽然我现在需要修改一个特定列中的输出,所以我可以按此列正确排序

这是我的密码:

$inputFile  = "C:\Data\expPasswords\expPasswords.csv"
$outputFile = "C:\Data\expPasswords\expPasswordsUp.csv"

$result = Import-Csv $inputFile |
            Select-Object @{ Name = 'Account'; Expression = { $_.Account  } },
                          @{ Name = 'Days until Expiry'; Expression = { $_.'time until password expires' } },
                          @{ Name = 'Email address'; Expression = { $_.'email address'  } }

# output on screen
$result | Sort-Object -Property 'Days until Expiry' | Format-Table -AutoSize

# output to csv
$result | Sort-Object -Property 'Days until Expiry' | Export-Csv -Path $outputFile -NoTypeInformation
我需要按“到期前天数”列进行排序。虽然当输出如下时,这会使其变得困难:

0分钟
0分钟
1天19小时
1天2小时
1天20小时
1天23小时
13小时
2天
20小时

基本上,我想做的是:
-如果少于1天,则取值为:今天
-删除小时和分钟块。
-因此,如果是13个小时,则将值设置为:今天
-如果该值为1天1小时35分钟,则将该值设为:1天


任何帮助都将不胜感激。;-)

我认为以下内容可能会有所帮助(当然,您需要编辑其中一些内容):


我认为以下内容可能会有所帮助(当然,您需要编辑其中一些内容):


很遗憾,你应该花时间从这个相当愚蠢的输出中理解一些道理,但这当然是可以做到的。 基本上,你所要做的就是找出字符串是否以数字开头,后跟单词“day”或“days”,然后把其余的都去掉。如果不是这样,则返回值应为“今天”

我认为最简单的方法是使用
switch-Regex

试一试

正则表达式详细信息:

^ Assert position at the beginning of the string \d Match a single character that is a “digit” (any decimal number in any Unicode script) + Between one and unlimited times, as many times as possible, giving back as needed (greedy) \ day Match the character string “ day” literally (case sensitive) s Match the character “s” literally (case sensitive) ? Between zero and one times, as many times as possible, giving back as needed (greedy) 输出:

Account Email address Days until Expiry Expiration Date ------- ------------- ----------------- --------------- User1 user1@yourcompany.com Today 6-4-2020 0:00:00 User6 user6@yourcompany.com Today 6-4-2020 0:03:00 User8 user8@yourcompany.com Today 6-4-2020 13:00:00 User4 user4@yourcompany.com Today 6-4-2020 20:00:00 User9 user9@yourcompany.com 1 7-4-2020 2:00:00 User2 user2@yourcompany.com 1 7-4-2020 19:00:00 User5 user5@yourcompany.com 1 7-4-2020 20:00:00 User7 user7@yourcompany.com 1 7-4-2020 23:00:00 User3 user3@yourcompany.com 2 8-4-2020 0:00:00
很遗憾,你应该花时间从这个相当愚蠢的输出中理解一些道理,但这当然是可以做到的。 基本上,你所要做的就是找出字符串是否以数字开头,后跟单词“day”或“days”,然后把其余的都去掉。如果不是这样,则返回值应为“今天”

我认为最简单的方法是使用
switch-Regex

试一试

正则表达式详细信息:

^ Assert position at the beginning of the string \d Match a single character that is a “digit” (any decimal number in any Unicode script) + Between one and unlimited times, as many times as possible, giving back as needed (greedy) \ day Match the character string “ day” literally (case sensitive) s Match the character “s” literally (case sensitive) ? Between zero and one times, as many times as possible, giving back as needed (greedy) 输出:

Account Email address Days until Expiry Expiration Date ------- ------------- ----------------- --------------- User1 user1@yourcompany.com Today 6-4-2020 0:00:00 User6 user6@yourcompany.com Today 6-4-2020 0:03:00 User8 user8@yourcompany.com Today 6-4-2020 13:00:00 User4 user4@yourcompany.com Today 6-4-2020 20:00:00 User9 user9@yourcompany.com 1 7-4-2020 2:00:00 User2 user2@yourcompany.com 1 7-4-2020 19:00:00 User5 user5@yourcompany.com 1 7-4-2020 20:00:00 User7 user7@yourcompany.com 1 7-4-2020 23:00:00 User3 user3@yourcompany.com 2 8-4-2020 0:00:00
您定义的约束可能会使它更加混乱。我只是将其转换为一种结构,使其易于排序:

$Result = ConvertFrom-Csv @'
"Account","Days until Expiry",  "Email address"
"Account1","0 minutes",         "Name1@gmail.com"
"Account2","1 day and 19 hours","Name2@gmail.com"
"Account3","2 days",            "Name3@gmail.com"
"Account4","20 hours",          "Name4@gmail.com"
"Account5","1 day and 20 hours","Name5@gmail.com"
"Account6","3 minutes",         "Name6@gmail.com"
"Account7","1 day and 23 hours","Name7@gmail.com"
"Account8","13 hours",          "Name8@gmail.com"
"Account9","1 day and 2 hours", "Name9@gmail.com"
'@


Function ConvertTo-TimeSpan([String]$String) {
    $Days    = If ($String -Match '\d+(?=\s*day)')    {$Matches[0]} Else {0}
    $Hours   = If ($String -Match '\d+(?=\s*hour)')   {$Matches[0]} Else {0}
    $Minutes = If ($String -Match '\d+(?=\s*minute)') {$Matches[0]} Else {0}
    $Seconds = If ($String -Match '\d+(?=\s*second)') {$Matches[0]} Else {0}
    New-TimeSpan -Days $Days -Hours $Hours -Minutes $Minutes -Seconds $Seconds
}

$Result | Sort @{e = {ConvertTo-TimeSpan $_.'Days until Expiry'}}
结果:

Account  Days until Expiry  Email address
-------  -----------------  -------------
Account1 0 minutes          Name1@gmail.com
Account6 3 minutes          Name6@gmail.com
Account8 13 hours           Name8@gmail.com
Account4 20 hours           Name4@gmail.com
Account9 1 day and 2 hours  Name9@gmail.com
Account2 1 day and 19 hours Name2@gmail.com
Account5 1 day and 20 hours Name5@gmail.com
Account7 1 day and 23 hours Name7@gmail.com
Account3 2 days             Name3@gmail.com

您定义的约束可能会使它更加混乱。我只是将其转换为一种结构,使其易于排序:

$Result = ConvertFrom-Csv @'
"Account","Days until Expiry",  "Email address"
"Account1","0 minutes",         "Name1@gmail.com"
"Account2","1 day and 19 hours","Name2@gmail.com"
"Account3","2 days",            "Name3@gmail.com"
"Account4","20 hours",          "Name4@gmail.com"
"Account5","1 day and 20 hours","Name5@gmail.com"
"Account6","3 minutes",         "Name6@gmail.com"
"Account7","1 day and 23 hours","Name7@gmail.com"
"Account8","13 hours",          "Name8@gmail.com"
"Account9","1 day and 2 hours", "Name9@gmail.com"
'@


Function ConvertTo-TimeSpan([String]$String) {
    $Days    = If ($String -Match '\d+(?=\s*day)')    {$Matches[0]} Else {0}
    $Hours   = If ($String -Match '\d+(?=\s*hour)')   {$Matches[0]} Else {0}
    $Minutes = If ($String -Match '\d+(?=\s*minute)') {$Matches[0]} Else {0}
    $Seconds = If ($String -Match '\d+(?=\s*second)') {$Matches[0]} Else {0}
    New-TimeSpan -Days $Days -Hours $Hours -Minutes $Minutes -Seconds $Seconds
}

$Result | Sort @{e = {ConvertTo-TimeSpan $_.'Days until Expiry'}}
结果:

Account  Days until Expiry  Email address
-------  -----------------  -------------
Account1 0 minutes          Name1@gmail.com
Account6 3 minutes          Name6@gmail.com
Account8 13 hours           Name8@gmail.com
Account4 20 hours           Name4@gmail.com
Account9 1 day and 2 hours  Name9@gmail.com
Account2 1 day and 19 hours Name2@gmail.com
Account5 1 day and 20 hours Name5@gmail.com
Account7 1 day and 23 hours Name7@gmail.com
Account3 2 days             Name3@gmail.com


您可以修改创建第一个CSV文件的源吗?这个愚蠢的。。。应该尽可能避免使用“漂亮的打印”内容破坏数据的决定——你现在已经看到了原因。[grin]不幸的是,csv是由第三方应用程序生成的,我无法控制,我需要在原始导出后处理数据。最终结果将被添加到一封HTML电子邮件中,该电子邮件需要“漂亮的打印”作为报告谢谢你的“为什么”。。。我对数据过早“人性化”表示哀悼。[grin]您可以修改创建第一个CSV文件的源吗?这个愚蠢的。。。应该尽可能避免使用“漂亮的打印”内容破坏数据的决定——你现在已经看到了原因。[grin]不幸的是,csv是由第三方应用程序生成的,我无法控制,我需要在原始导出后处理数据。最终结果将被添加到一封HTML电子邮件中,该电子邮件需要“漂亮的打印”作为报告谢谢你的“为什么”。。。我对数据过早“人性化”表示哀悼。[grin]真的认为这一条会起作用,但不幸的是,显示的结果是一行,其中一条帐户和电子邮件地址记录为空值,在到期前的5天内。将不得不再次检查我所做的更改,以确保其设置正确。有没有其他方法可以让我设定如下规则:分钟、小时、天,这样至少我可以得到正确的顺序。目前,它按第一个数字排序;e、 g 7小时将在2天后出现,在设置订单之前,它应该检查是在数字之后的分钟、小时还是天。完全同意你的观点。非常愚蠢的输出必须处理。@brokencrow抱歉,有点匆忙,粘贴错误。代码现在更新了,我添加了一个示例输出。总是随商品一起提供。你是一个代码忍者:-)一切正常。感谢you@brokencrow谢谢你的反馈!我真的认为这一个会起作用,但不幸的是,显示的结果是一行,其中一个帐户和电子邮件地址记录为空值,在到期前的5天内。将不得不再次检查我所做的更改,以确保其设置正确。有没有其他方法可以让我设定如下规则:分钟、小时、天,这样至少我可以得到正确的顺序。目前,它按第一个数字排序;e、 g 7小时将在2天后出现,在设置订单之前,它应该检查是在数字之后的分钟、小时还是天。完全同意你的观点。非常愚蠢的输出必须处理。@brokencrow抱歉,有点匆忙,粘贴错误。代码现在更新了,我添加了一个示例输出。总是随商品一起提供。你是一个代码忍者:-)一切正常。感谢you@brokencrow谢谢你的反馈!我也测试过这个,但不幸的是我不能手动添加我必须使用的值。原始结果集是csv文件中的所有列值,这些值将发生更改。是的,我已经考虑到了这一点。我做了一个小的更新来显示你的属性。到底是什么“似乎无法正常工作”?此代码与以前略有不同,我将以这种方式进行测试,并让您知道我是如何更改函数的,而只是更改输入以显示其工作方式的。为了更好地理解
Timespan
结构(可以更精细地排序!),您还可以添加一个新列,如:
$Result | Select*,@{n='Timespan until expire';e={ConvertTo Timespan$.'Days until expire'}| Sort'Timespan until expire'
我也测试过这个列,但不幸的是我可以