Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
170 views
in Technique[技术] by (71.8m points)

Odd Powershell Substring/Replace Issue Occurring

I have to update a file with one line every day in three different sections of the line.

The line in the file on January 15th before the update was as follows:

XXXXXX 01130113352021013115126XXXX 2005000113 XXX XXX XXX I

So, the line is divided by spaces into 7 segments. I have to update the first 4 characters of the second segment with MMDD<-1>, the 13 characters prior to the XXXX in the second segment with YYYYJJJHHMMSS<-1> and then the last four digits of the third segment with MMDD<-1>

Here is my code:

#get the year minuse 1 day, get the day of the year minuse 1 day, get the current time 
$yeardayofyeartime = (get-date).AddDays(-1).ToString("yyyy") + (get-date).AddDays(-1).dayofyear.ToString("000") + (get-date).ToString("HHmmss")
Add-Content -Path $logpath -Value "The year, Julian date, and time is:"
Add-Content -Path $logpath -Value $yeardayofyeartime

#get the current month and day minus 1
$monthday = (get-date).AddDays(-1).ToString("MMdd")
Add-Content -Path $logpath -Value "The month and the day is: $monthday."
Add-Content -Path $logpath -Value $monthday

$Content = Get-Content $source
Add-Content -Path $logpath -Value "Content in the file before update is:"
Add-Content -Path $logpath -Value $Content

$Content.Replace($Content.Substring(12, 4), $monthday).Replace($Content.Substring(22, 13), $yeardayofyeartime).Replace($Content.Substring(51, 4), $monthday) | Out-File -encoding ASCII $source

Add-Content -Path $logpath -Value "Content in the file after update:"
Get-Content $source | Add-Content -Path $logpath

Add-Content -Path $logpath -Value "*********************************************************************************************************"
    
exit 0

The odd thing is that it's also updating 16,4 with MMDD<-1> and I don't know why. Here's what I've created a log to monitor these changes and here's what I found. These logs start on the 15th.

The year, Julian date, and time is: 2021014060002 The month and the day is: 0114. 0114 Content in the file before update is: XXXXXX 01130113352021013115126XXXX 2005000113 XXX XXX XXX I
Content in the after update: XXXXXX 01140114352021014060002XXXX 2005000114 XXX XXX XXX I


The year, Julian date, and time is: 2021015060002 The month and the day is: 0115. 0115 Content in the file before update is: XXXXXX 01140114352021014060002XXXX 2005000114 XXX XXX XXX I
Content in the after update: XXXXXX 01150115352021015060002XXXX 2005000115 XXX XXX XXX I


The year, Julian date, and time is: 2021016060002 The month and the day is: 0116. 0116 Content in the file before update is: XXXXXX 01150115352021015060002XXXX 2005000115 XXX XXX XXX I
Content in the after update: XXXXXX 01160116352021016060002XXXX 2005000116 XXX XXX XXX I


The year, Julian date, and time is: 2021017060002 The month and the day is: 0117. 0117 Content in the file before update is: XXXXXX 01160116352021016060002XXXX 2005000116 XXX XXX XXX I
Content in the after update: XXXXXX 01170117352021017060002XXXX 2005000117 XXX XXX XXX I


The year, Julian date, and time is: 2021018060002 The month and the day is: 0118. 0118 Content in the file before update is: XXXXXX 01170117352021017060002XXXX 2005000117 XXX XXX XXX I
Content in the after update: XXXXXX 01180118352021018060002XXXX 2005000118 XXX XXX XXX I


The year, Julian date, and time is: 2021019060002 The month and the day is: 0119. 0119 Content in the file before update is: XXXXXX 01180118352021018060002XXXX 2005000118 XXX XXX XXX I
Content in the after update: XXXXXX 01190119352021019060002XXXX 2005000119 XXX XXX XXX I


The year, Julian date, and time is: 2021020060002 The month and the day is: 0120. 0120 Content in the file before update is: XXXXXX 01190119352021019060002XXXX 2005000119 XXX XXX XXX I
Content in the after update: XXXXXX 01200120352021020060002XXXX 2005000120 XXX XXX XXX I


Any ideas why this part is updating as well?

question from:https://stackoverflow.com/questions/65848850/odd-powershell-substring-replace-issue-occurring

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I wouldn't use the repeated .Replace() methods here, but rather split the string into segments and do the replacements on each segment. Then rejoin these to form the new content:

$segments = $content -split ' '
# split the second segment into 4 parts
$subs = $segments[1] -split '^(d{4})(d{6})(d{13})(.*)' -ne ''
$subs[0] = $monthday
$subs[2] = $yeardayofyeartime
# rejoin the sub parts to form the new $segment[1]
$segments[1] = $subs -join ''

# replace the third segment
# or use $segments[2] = $segments[2] -replace '(.*)d{4}$', "`$1$monthday"
$segments[2] = $segments[2].Substring(0,6) + $monthday

# rejoin the updated segments to form the new content line
$content = $segments -join ' '

To explain what @g.sulman asked in his comment: "What does -ne '' do on the $subs = ... line"

PowerShell's -split operator has a gotcha:

When the input string to splits starts (and in this case also ends) in a regex match, -split treats the first and last element of the split to be an empty string.

Demo:

$subs = '01130113352021013115126XXXX' -split '^(d{4})(d{6})(d{13})(.*)'
for ($i = 0; $i -lt $subs.Count; $i++) {
    '{0}: {1}' -f $i, $subs[$i]
}

Result:

0: 
1: 0113
2: 011335
3: 2021013115126
4: XXXX
5:

By passing the resulting array to -ne '', we filter out these empty strings:

$subs = '01130113352021013115126XXXX' -split '^(d{4})(d{6})(d{13})(.*)' -ne ''
for ($i = 0; $i -lt $subs.Count; $i++) {
    '{0}: {1}' -f $i, $subs[$i]
}

Result:

0: 0113
1: 011335
2: 2021013115126
3: XXXX

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...