问题描述
我有一个这样的 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:\Users\me\Desktop\info.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:\Users\me\Desktop\info.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:\Users\me\Desktop\info.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 条目添加一个制表符。
有没有人对此有任何想法或如何遍历每个数组条目,然后用新条目替换旧条目?
编辑:每一行都是单行 tab
分隔在 2 列之间。
解决方法
如果它只处理最后一行,那么这意味着我们不会在进行时保存我们在 for-each 循环中所做的事情。
由于它没有被保存,所以只有最后一行要处理的会被更新。
让我们看看您的 forEach
。
foreach ($product in $arrayoutput) {
if ($product.length -le 7) {
$addtab = "$product"+"`t"
$endresult = $where.replace($product,$addtab)
}
}
这是每次都重新保存$endResult
,并将其保存为$where
的值,当您将一个值替换为另一个值时,这意味着每次执行此foreach时都会替换一行,然后你下次再做一次,下一次。
您没有保留更改,因为您每次都使用针对 $endResult
的一个更改操作重新保存 $where
。 这是错误。
相反,我们只需进行两次更改即可使其工作。首先,在脚本开始时,我们将复制所有未经编辑的原始文本文件 $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
,保留之前的编辑。我没有与您相同的源文件来重新创建它,但它应该可以工作。
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:\Test\file.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 "$path\source.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 >> $path\result.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 $path\result.txt)) | % {$_.Remove(10,20)}
或者替换Headers并再次保存在txt文件中
([string[]](Get-Content $path\result.txt)) | % {$_.Replace("Name","List:")} | % {$_.Replace("Value","Id:")}