PowerShell替换循环(关闭),但只有数组中的最后一个对象受到影响



我有一个这样的txt文件,但如果LIST列中的每个条目中有7个或更少的字符(包括换行的双引号(,我需要添加一个选项卡,然后替换为文件,使其格式美观(该文件只能是txt,以其当前的格式等(:

当前

List:       ID:
"izzak" "QWERTY654POI"
"swortz23"  "00ERTY654POI"
"campingou" "QWERTY454POI"
"dark1est"  "QWERTY654POI"
"muffin0"   "QWERTY654POI"
"parly" "25ERTY654POI"
"ggghsle"   "QWE78Y654POI"
"fie4lder"  "QWERTY654POI"
"67532" "QWERTY654POI"
"urquhart"  "11ERTY654POI"
"bbs3"  "QWERTY654POI"

需要看起来像这样:

List:       ID:
"izzak"     "QWERTY654POI"
"swortz23"  "00ERTY654POI"
"campingou" "QWERTY454POI"
"dark1est"  "QWERTY654POI"
"muffin0"   "QWERTY654POI"
"parly"     "25ERTY654POI"
"ggghsle"   "QWE78Y654POI"
"fie4lder"  "QWERTY654POI"
"67532"     "QWERTY654POI"
"urquhart"  "11ERTY654POI"
"bbs3"      "QWERTY654POI"
$where = Get-Content C:UsersmeDesktopinfo.txt
#pull any text on each line before a tab (gets first column if wrapped in double quotes)
$pattern = '(".*")(?:t)'
$arrayoutput = (Get-Content -Path "C:UsersmeDesktopinfo.txt" | Select-String $pattern -AllMatches | ForEach-Object { $_.Matches.Value }).Trim()
foreach ($product in $arrayoutput) {
   if ($product.length -le 7) {
$addtab = "$product"+"`t"
$endresult = $where.replace($product, $addtab)
}
 }
$endresult | Set-Content -Path "C:UsersmeDesktopinfo.txt"

结果如下所示(最后一行被标记,但没有其他行(:

"izzak" "QWERTY654POI"
"swortz23"  "00ERTY654POI"
"campingou" "QWERTY454POI"
"dark1est"  "QWERTY654POI"
"muffin0"   "QWERTY654POI"
"parly" "25ERTY654POI"
"ggghsle"   "QWE78Y654POI"
"fie4lder"  "QWERTY654POI"
"67532" "QWERTY654POI"
"urquhart"  "11ERTY654POI"
"bbs3"      "QWERTY654POI"

如果LIST列中有多个条目小于或等于7(计算其周围的双引号;否则为5(,则我的代码只会在LAST条目中添加一个选项卡。

有人对此有什么想法吗?或者如何迭代每个数组条目,然后用新条目替换旧条目?

EDIT:每一行都是在两列之间分隔的单个tab

TAB字符的长度可变。这取决于当时正在读取文件的应用程序,所以我会选择使用空格字符来对齐字符串。如果您使用单间距字体,这看起来总是正确的
(在HTML中,您可以将结果嵌入到<pre>..</pre>标记中以确保这一点(

# create two List objects for the left and right parts of each string
$left  = [System.Collections.Generic.List[string]]::new()
$right = [System.Collections.Generic.List[string]]::new()
Get-Content -Path 'D:Testfile.txt' | ForEach-Object {
$l, $r = $_ -split 's+', 2
$left.Add($l)
$right.Add($r)
}
# calculate the max length of the left strings under 'List'
$maxpad = ($left | Measure-Object -Property Length -Maximum).Maximum + 1 # + 1 for padding
# now loop through the lists and output padded lines
$result = for ($i = 0; $i -lt $left.Count; $i++) {
"{0,-$maxpad}{1}" -f $left[$i], $right[$i]
# or use
#'{0}{1}' -f $left[$i].PadRight($maxpad), $right[$i]
}
$result

输出:

List:       ID:

"izzak"     "QWERTY654POI"
"swortz23"  "00ERTY654POI"
"campingou" "QWERTY454POI"
"dark1est"  "QWERTY654POI"
"muffin0"   "QWERTY654POI"
"parly"     "25ERTY654POI"
"ggghsle"   "QWE78Y654POI"
"fie4lder"  "QWERTY654POI"
"67532"     "QWERTY654POI"
"urquhart"  "11ERTY654POI"
"bbs3"      "QWERTY654POI"

通过使用哈希表,它非常有用,可能在未来的工作中派上用场

$clear = (Get-content "$pathsource.txt").Split(' ') | % { $_.Split(' ')} | ? {$_ -notcontains [string]::Empty}; $hash = @{}; For($i = 0;$i -lt $clear.count; $i=$i+2){$hash.Add($clear[$i], $clear[$i+1])}; $hash >> $pathresult.txt

txt文件的结果:

Name                           Value
----                           -----
"urquhart"                     "11ERTY654POI"
"campingou"                    "QWERTY454POI"
"muffin0"                      "QWERTY654POI"
"parly"                        "25ERTY654POI"
"ggghsle"                      "QWE78Y654POI"
"izzak"                        "QWERTY654POI"
"bbs3"                         "QWERTY654POI"
"fie4lder"                     "QWERTY654POI"
"swortz23"                     "00ERTY654POI"
"dark1est"                     "QWERTY654POI"
"67532"                        "QWERTY654POI"

当然,现在你可以根据自己的意愿编辑这个表,例如使用Remove方法删除多余的空格条目,例如

([string[]](Get-Content $pathresult.txt)) | % {$_.Remove(10,20)}

或者替换Headers并将其再次保存在txt文件中

([string[]](Get-Content $pathresult.txt)) | % {$_.Replace("Name", "List:")} |  % {$_.Replace("Value", "Id:")}

如果它只处理最后一行,那么这意味着我们不会在进行每个循环时保存我们在中所做的内容。

由于它不会在我们进行的过程中保存,因此只会更新最后一行要处理的内容
让我们看看您的forEach

foreach ($product in $arrayoutput) {
if ($product.length -le 7) {
$addtab = "$product"+"`t"
$endresult = $where.replace($product, $addtab)
}
}

这就是每次重新保存$endResult,并将其保存为$where的值,当您将一个值替换为另一个值时,这意味着每次遍历此foreach时,都会替换一行,然后在下一次和下一次再次执行。

您不会保留更改,因为您每次都对$where执行一次更改操作来重新保存$endResult这就是bug

相反,我们只需两次更改就可以使其发挥作用。首先,在脚本开始时,我们将复制所有$where,它是原始的、未经编辑的文本文件,并将其存储为$endResult。然后,我们修改循环,只编辑$endResult,有效地在循环中逐行修复文件。

#store the unedited file as `$endResult`
$endresult = $where 
foreach ($product in $arrayoutput) {
if ($product.length -le 7) {
$addtab = "$product"+"`t"
#as we progress through the loop, we are cleaning up the endresult file line by line
$endresult = $endresult.replace($product, $addtab)
}
}

这将在进行时更新$endResult,保留以前的编辑。我没有和你相同的源文件来重新创建它,但它应该可以工作。

最新更新