Powershell循环将任何行存储在来自多个文件的变量中

Posted

技术标签:

【中文标题】Powershell循环将任何行存储在来自多个文件的变量中【英文标题】:Powershell loop to store any line in variable from multiple files 【发布时间】:2022-01-09 21:56:31 【问题描述】:

我这里有一个小情况,对你来说可能很简单。 背景: 我有 3 个文件:mobile.txtcontract.txtname.txt 所有文件的格式都像每一行都应该引用其他文件的同一行...

示例:

mobile.txt
0606060606
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循环将任何行存储在来自多个文件的变量中的主要内容,如果未能解决你的问题,请参考以下文章

将目录文件夹名称存储到阵列 Powershell

在 .bat 文件中使用 PowerShell,将一个字符串替换为多个字符串

循环文件的 N 行并存储在多个列表中

使用 PowerShell 将多个 CSV 文件合并为一个

使用来自 Textfile 的文件创建 7-Zip 存档 - Powershell

如何在 PowerShell 中将文件作为流逐行处理