Powershell循环将任何行存储在来自多个文件的变量中
Posted
技术标签:
【中文标题】Powershell循环将任何行存储在来自多个文件的变量中【英文标题】:Powershell loop to store any line in variable from multiple files 【发布时间】:2022-01-09 21:56:31 【问题描述】:我这里有一个小情况,对你来说可能很简单。
背景:
我有 3 个文件:mobile.txt
、contract.txt
和 name.txt
所有文件的格式都像每一行都应该引用其他文件的同一行...
示例:
mobile.txt0606060606
0607070707
0608080808
合同.txt
123654
456985
152364
name.txt
John Doe
Miss 1
Mister 2
我想要一个 foreach
之类的循环来逐行提取变量中的数据并将表创建为:
0606060606;123654;John Doe
0607070707;456985;Miss 1
0608080808;152364;Mister 2
当然,这对您来说真的很简单。 我只设法将整个文件存储到一个变量中,而不是创建一个表。
大家干杯。
问题 #2(在回答问题 #1 后更新):
您好,使用此方法可以正常工作 谢谢各位。
感谢您,我现在有一个包含 115 行的文件:
0606060606;123654;John Doe
0607070707;456985;Miss 1
0608080808;152364;Mister 2
我有另一个包含此类内容的文件:
Smart Pro 5h 3Go ;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-accès international;00,00
Abonnement Options-Option Voyage;00,00
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte;-3,00
----------------------- Page 30----------------------
Smart Pro 5h 3Go ;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-accès international;00,00
Abonnement Options-Option Voyage;00,00
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte;-3,00
----------------------- Page 31----------------------
Smart Pro 5h 3Go;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte ;-3,00
----------------------- Page 32----------------------
现在我必须像这样匹配它们: 文件 1 的第 1 行被复制到分隔符之间的第一个内容 文件1的第2行被复制到分隔符之间的第二个内容 文件 1 的第 3 行被复制到分隔符之间的第三个内容 分隔符可以是另一个字符串,而不是带有页码的字符串。
我希望在最终文件中出现这种类型的输出:
0606060606;123654;John Doe;Smart Pro 5h 3Go ;44,00
0606060606;123654;John Doe;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0606060606;123654;John Doe;Abonnement Options-accès international;00,00
0606060606;123654;John Doe;Abonnement Options-Option Voyage;00,00
0606060606;123654;John Doe;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0606060606;123654;John Doe;OCC-option illimité intra-compte offerte;-3,00
0607070707;456985;Miss 1;Smart Pro 5h 3Go ;44,00
0607070707;456985;Miss 1;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0607070707;456985;Miss 1;Abonnement Options-accès international;00,00
0607070707;456985;Miss 1;Abonnement Options-Option Voyage;00,00
0607070707;456985;Miss 1;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0607070707;456985;Miss 1;OCC-option illimité intra-compte offerte;-3,00
0608080808;152364;Mister 2;Smart Pro 5h 3Go;44,00
0608080808;152364;Mister 2;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0608080808;152364;Mister 2;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0608080808;152364;Mister 2;OCC-option illimité intra-compte offerte ;-3,00
我陷入了无休止的循环......
【问题讨论】:
您能与我们分享您解决此问题的尝试吗? 【参考方案1】:你使用
$mobile_txt = @( Get-Content mobile.txt )
$contract_txt = @( Get-Content contract.txt )
$name_txt = @( Get-Content name.txt )
而不是硬编码文件:
$mobile_txt = @'
0606060606
0607070707
0608080808
'@ -split [System.Environment]::NewLine
$contract_txt = @'
123654
456985
152364
'@ -split [System.Environment]::NewLine
$name_txt = @'
John Doe
Miss 1
Mister 2
'@ -split [System.Environment]::NewLine
for ( $ii = 0;
$ii -lt ( ( $mobile_txt.Count,
$contract_txt.Count,
$name_txt.Count | Measure-Object -Minimum).Minimum);
$ii++ )
[PSCustomObject] @
mobile = $mobile_txt[$ii];
contract = $contract_txt[$ii];
name = $name_txt[$ii]
;
结果:.\SO\70215879.ps1
mobile contract name
------ -------- ----
0606060606 123654 John Doe
0607070707 456985 Miss 1
0608080808 152364 Mister 2
【讨论】:
我觉得应该是-Maximum).Maximum
而不是-Minimum).Minimum
吧?
@SantiagoSquarzon 否。如果计数(分别)为 3、3、2,则 Maximum
为 3,$name_txt[2]
导致错误 索引超出数组范围。我>
不确定你的意思,(1,2,3)[3]
只会返回null
而不是例外。此外,如果其中一个数组的元素比其他数组多 20 个,你会截断它吗?
我使用Set-StrictMode -Version latest
设置和(1,2,3)[3]
导致Index was outside the bounds of the array
。是的,截断是任务结构不良的结果……
@SantiagoSquarzon 我知道Set-StrictMode
默认是关闭的。但是,我认为这是一种不好的做法,请参见例如powershell-guru - 虽然这只是一种意见:the PowerShell default can be both a blessing and a curse...【参考方案2】:
文件的行数可能不同,在这种情况下很容易丢失信息。 为了实现这一点,并为所有行创建输出,但可能存在空字段,您可以读取文件并从行创建哈希表。
$i = 0
$mobile = @
Get-Content -Path 'X:\mobile.txt' | ForEach-Object $mobile[$i++] = $_
$i = 0
$contract = @
Get-Content -Path 'X:\contract.txt' | ForEach-Object $contract[$i++] = $_
$i = 0
$name = @
Get-Content -Path 'X:\name.txt' | ForEach-Object $name[$i++] = $_
# determine the maximum number of lines found in tthe input files
$maxItems = ($mobile.Count, $name.Count, $contract.Count | Measure-Object -Maximum).Maximum
# next, combine and output.
# this won't throw an exception if an item is not present
# in any of the files, but insert an empty field instead.
for ($i = 0; $i -lt $maxItems; $i++)
output a line as shown in your question
'0;1;2' -f $mobile[$i], $contract[$i], $name[$i]
或者,如果我可以建议,组合为 object,稍后另存为 CSV 文件
$result = for ($i = 0; $i -lt $maxItems; $i++)
# output an object that gets collected in variable $result
[PsCustomObject]@
Mobile = $mobile[$i]
Contract = $contract[$i]
Name = $name[$i]
# view on console
$result
# write to CSV file
$result | Export-Csv -Path 'X:\MobileCombined.csv' -Delimiter ';' -NoTypeInformation
【讨论】:
以上是关于Powershell循环将任何行存储在来自多个文件的变量中的主要内容,如果未能解决你的问题,请参考以下文章
在 .bat 文件中使用 PowerShell,将一个字符串替换为多个字符串