我有一个很大的.txt文件,其中包含记录,其中每条记录中的日期字符串需要增加2天,这将更新其右侧包含破折号的字段---------那个日期。例如,一条记录包含以下记录数据:
1440149049845_20191121000000 2019年11月22日-------- 0.000 0.013
我要用11/24/2019代替--------破折号(在日期11/22/2019加上2天),以便显示为:
1440149049845_20191121000000 11/22/2019 11/24/2019 0.000 0.013
我在单个记录上执行了替换操作,但是需要遍历整个.txt文件以更新所有记录。这是我尝试过的:
$inputRecords = get-content '\\10.12.7.13\vipsvr\Rancho\MRDF_Report\_Report.txt'
foreach ($line in $inputRecords)
{
$item -match '\d{2}/\d{2}/\d{4}'
$inputRecords -replace '-{2,}',([datetime]$matches.0).adddays(2).tostring('MM/dd/yyyy') -replace '\b0\.000\b','0.412'
}
我收到一个PS错误,指出:“无法将null转换为类型“ System.DateTime”
答案 0 :(得分:0)
您大多有正确的想法,但是这里有一些建议的更改,但不完全按此顺序进行:
使用新文件,而不是尝试替换旧文件。
一次遍历一行,替换------,写入新文件。
使用'-match'而不是'-replace',因为正如您将在下面看到的那样,您需要比简单的'-replace'允许更多的操作捕获。
使用[datetime] :: parseexact而不是尝试强制转换捕获的文本。
[string[]]$inputRecords = get-content ".\linesource.txt"
[string]$outputRecords
foreach ($line in $inputRecords) {
[string]$newLine = ""
[regex]$logPattern = "^([\d_]+) ([\d/]+) (-+) (.*)$"
if ($line -match $logPattern) {
$origDate = [datetime]::parseexact($Matches[2], 'mm/dd/yyyy', $null)
$replacementDate = $origDate.adddays(2)
$newLine = $Matches[1]
$newLine += " " + $origDate.toString('mm/dd/yyyy')
$newLine += " " + $replacementDate.toString('mm/dd/yyyy')
$newLine += " " + $Matches[4]
} else {
$newLine = $line
}
$outputRecords += "$newLine`n"
}
$outputRecords.ToString()
即使您不使用整个解决方案,也希望至少有部分解决方案会对您有所帮助。
答案 1 :(得分:0)
对不起,为什么我们要使用RegEx做这么简单的事情?
如果文件中有不同格式的行,我可以看到它,您想确保您没有在操纵意外的行,但这未在问题中指出。即使如此,似乎您也不需要匹配该行中的任何内容。似乎在空格之间定界,这会使简单的拆分容易得多。
示例:
$File = "C:\temp\Test.txt"
$Output =
ForEach( $Line in Get-Content $File)
{
$TmpArray = $Line.Split(' ')
$TmpArray[2] = (Get-Date $TmpArray[1]).AddDays(2).ToString('M/dd/yyyy')
$TmpArray -join ' '
}
数组中的第三个元素进行计算并重新分配值...
请注意,没有使用+ =运算符,与仅将输出分配给变量相比,这非常慢。我不会做任何事情,但考虑到我们不知道文件有多大...此外,在“ mm / dd / yyyy”之前给出的字符串格式将导致本月的00,例如“ 00” / 22/2019”,因此我将其更改为“ M / dd / yyyy”
如果需要,您仍然可以添加逻辑以跳过不必要的行...
您可以将$ Output发送到类似$Output | Out-File <FilePath>
的文件中
或者可以将其转换为单个管道,使用| ForEach{...}
而不是ForEach(.. in ..)
直接输出到文件如果文件确实很大并且在内存中保留$ Output是一个很好的问题替代。
让我知道是否有帮助。
答案 2 :(得分:0)
使用来自adamt8和Steven的建议代码,我添加了2条echo语句以显示变量$ logpattern和$ line中显示的内容,因为它无法识别要更新的字符模式。这是回显中显示的内容:
选项MatchTimeout RightToLeft
CalNOD01 1440151020208_20191205000000 12/06/2019 12/10/2019
无-00:00:00.0010000错误
CalNOD01 1440151020314_20191205000000 2019年6月12日--------
无-00:00:00.0010000错误
这是渲染的输出:
CalNOD01 1440151020208_20191205000000 12/06/2019 12/10/2019
CalNOD01 1440151020314_20191205000000 12/06/2019 --------
这是使用的代码: