0

I have a situation here and I would like to share it with you to ask for help.

I have a TXT file that I receive every day and I need to import it into my ERP, however, this file comes with a line break that we have to manually adjust img1

And when adjusted, it looks like this: img2

{
    Write-Error "Informe um arquivo para leitura"
    Return
}

$arquivo = $args[0]

if(![System.IO.File]::Exists($arquivo)) 
{
    Write-Error "Arquivo nao encontrado: $arquivo"
    Return
}

$tamanhoEsperado = 240
$ultimoTamanho = 0

foreach($linha in [System.IO.File]::ReadLines($arquivo))
{
    if ($linha.length -gt 0)
    {
        if (!($linha.length -eq $tamanhoEsperado) -And (($linha.length + $ultimoTamanho) -eq $tamanhoEsperado))
        {
            Write-Host -NoNewLine $linha
            $ultimoTamanho += $linha.length
        }
        else
        {
            if ($ultimoTamanho -gt 0) 
            {
                Write-Host
            }
            Write-Host -NoNewLine $linha
            $ultimoTamanho = $linha.length
        }
    } 
    else 
    {
        Write-Host
    }
}

But I am not able to make the process automatic with this script.

Powershell will look for the TXT file in a specific folder, validate if the file has 240 positions and if not, correct that line break shown in img1. Would that be possible?

1 Answers1

0

Note:

  • Write-Host is typically the wrong tool to use, unless the intent is to write to the display only, bypassing the success output stream and with it the ability to send output to other commands, capture it in a variable, or redirect it to a file. To output a value, use it by itself; e.g., $value instead of Write-Host $value (or use Write-Output $value). See this answer for more information.

  • Therefore, your code only produced for-display output, not data.


Try something like the following:

$fragment = ''
$correctedLines = 
  foreach ($line in [System.IO.File]::ReadLines($arquivo)) {
    if ($fragment) {    # The previous line was incomplete.
      $fragment + $line # Concatenate the fragment with the current line and output.
      $fragment = ''    # Reset the fragment variable.
    } elseif ($line.Length -ne 240) {
      $fragment = $line # Save the fragment and continue.
    } else {
      $line             # Complete line -> output it.
    }
  }

Note the use of implicit output (e.g., $line) and that you can directly collect all output from the foreach statement in a variable.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • sorry I didn't understand how to apply this to my code. Can you clarify please? – Lucas Alexandre Vieira de Alme Jul 28 '22 at 16:39
  • @LucasAlexandreVieiradeAlme, `$correctedLines` is the array of repaired lines, which you can send to a file with `$correctedLines | SetContent ...`, for instance. If you don't want to collect the corrected lines in memory first, enclose the entire `foreach` statement in `& { ... }` and pipe that to `Set-Content`. I don't know if my loop body implements all the logic you need (the Portuguese variable names didn't help), but you should be able to adapt it easily. – mklement0 Jul 28 '22 at 17:48