Powershell:逐行读取文本文件并在“ |”

时间:2018-12-13 15:14:04

标签: powershell csv text-parsing

我无法使用“ |”将行拆分为数组在文本文件中,并按一定顺序重新组装。有多个行,如文本文件中的原始行。

这是原始行:

80055555|Lastname|Firstname|AidYear|DCDOCS|D:\BDMS_UPLOAD\800123456_11-13-2018 14-35-53 PM_1.pdf

我需要它看起来像这样:

80055555|DCDOCS|Lastname|Firstname|AidYear|D:\BDMS_UPLOAD\800123456_11-13-2018 14-35-53 PM_1.pdf

这是我正在使用的代码:

$File = 'c:\Names\Complete\complete.txt'
$Arr = $File -split '|'
foreach ($line in Get-Content $File)
{
  $outputline = $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + 
    "@@" + $Arr[5] |
      Out-File -filepath "C:\Names\Complete\index.txt" -Encoding "ascii" -append 
}

3 个答案:

答案 0 :(得分:1)

您需要自行处理文件的每一行,然后将其拆分。

$File = get-content "D:\test\1234.txt"
foreach ($line in $File){
    $Arr = $line.Split('|')
    [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5] 
}
$OutputFile | out-file -filepath "D:\test\4321.txt" -Encoding "ascii" -append 

edit:基于-join和避免使用+=来构建数组的替代建议,请向LotPings致谢(效率低下,因为它在每次迭代时都会重建数组):

$File = get-content "D:\test\1234.txt"
$OutputFile = foreach($line in $File){($line.split('|'))[0,4,1,2,3,5] -Join '|'}
$OutputFile | out-file -filepath "D:\test\4321.txt" -Encoding "ascii"

答案 1 :(得分:1)

由于您的输入文件实际上是不带标题的CSV文件,并且字段之间用竖线符号|隔开,所以为什么不这样使用Import-Csv

$fileIn  = 'C:\Names\Complete\complete.txt'
$fileOut = 'C:\Names\Complete\index.txt'
(Import-Csv -Path $File -Delimiter '|' -Header 'Item','LastName','FirstName','AidYear','Type','FileName' | 
    ForEach-Object {
        "{0}|{1}|{2}|{3}|{4}|{5}" -f $_.Item, $_.Type, $_.LastName, $_.FirstName, $_.AidYear, $_.FileName
    }
) | Add-Content -Path $fileOut -Encoding Ascii

答案 2 :(得分:1)

要提供更多PowerShell惯用的解决方案:

if(!values.includes(e.parameter[headers[i]][j])){       
    row.push(e.parameter[headers[i]]);
}

请注意,PowerShell的索引语法(在# Sample input line. $line = '80055555|Lastname|Firstname|AidYear|DCDOCS|D:\BDMS_UPLOAD\800123456_11-13-2018 14-35-53 PM_1.pdf' # Split by '|', rearrange, then re-join with '|' ($line -split '\|')[0,4,1,2,3,5] -join '|' 内部)具有足够的灵活性,可以接受要提取的任意 array (列表)索引。

还要注意[...]的RHS操作数是-split,即转义的 \|个字符,因为|具有特殊的意思(因为它被解释为 regex )。

将它们放在一起:

|

关于您尝试过的事情

  

$File = 'c:\Names\Complete\complete.txt' Get-Content $File | ForEach-Object { ($_ -split '\|')[0,4,1,2,3,5] -join '|' } | Out-File -LiteralPath C:\Names\Complete\index.txt -Encoding ascii

从根本上讲,问题在于$Arr = $File -split '|'操作应用于输入的文件路径,而不是文件的 content

第二,如上所述,要以文字 -split字符进行拆分,必须将|传递给\|,因为它期望 regex (正则表达式)。

此外,与其在-split的循环内使用Out-File ,不如在{{1 }},如上所示。