Ler arquivos, extrair caracteres, anexar ao início de todas as linhas, remover cabeçalho e rodapé, concatenar todos os arquivos

Ler arquivos, extrair caracteres, anexar ao início de todas as linhas, remover cabeçalho e rodapé, concatenar todos os arquivos

Eu tenho um grande conjunto de arquivos de texto ASCII que preciso modificar com o conteúdo encontrado no arquivo e concatená-los todos em um arquivo de resumo. Tive sucesso moderado usando uma abordagem passo a passo até agora. Mas eu gostaria de fazer isso de uma só vez e não consegui descobrir. Escrevi um script no PowerShell que fará o que desejo para um arquivo, mas não consigo descobrir como modificá-lo para todos os arquivos da pasta. Tenho lutado com o loop e as seções finais de concatenação de arquivos.

Aqui está minha estrutura básica de arquivos:

Arquivo1.txt

Linha1 - abc123 - cabeçalho (quero retirar os caracteres 2,3 e 4 daqui e adicioná-los às linhas de dados)
Linha2 - dados1
Linha3 - dados2
LinhaN - abc123 - rodapé (uma duplicata do cabeçalho)

Arquivo2.txt

Linha1 - efg456
Linha2 - dados3
Linha3 - dados4
LinhaN - efg456

ArquivoN.txt

Linha1 - hij789
Linha2 - dados5
Linha3 - dados6
LinhaN - hij789

Gostaria que o arquivo de saída final tivesse a seguinte estrutura com o cabeçalho e rodapés removidos e o conteúdo extraído do cabeçalho em uma nova coluna no início do arquivo (são arquivos de largura fixa):

Final.txt

Linha1 - bc1data1
Linha2 - bc1data2
Linha3 - fg4data3
Linha4 - fg4data4
Linha5 - ij7data5
Linha6 - ij7data6

Consegui resolver isso para um arquivo e coloquei o código abaixo:

cd "C:\Data\Files\"
$S1 = Get-Content File1.txt -First 1
$S2 = $S1.Substring(2,3)
Get-Content File1.txt | ForEach-Object {Add-Content a.txt "$S2$_"}
Get-Content a.txt | Select -Skip 1 | Select -SkipLast 1 | Set-Content out.txt
# extract header line
# limit to characters of interest
# append to the beginning of each line in file
# append all files together w/o first & last line

Idealmente, eu também poderia fazer isso sem o arquivo indesejado a.txt, mas até agora só consegui fazê-lo funcionar gravando em um arquivo separado. Quaisquer sugestões/dicas serão apreciadas, pois sou bastante novo no PowerShell (algumas horas de prática).

Responder1

## Q:\Test\2017\08\25\SU_1244148.ps1

Set-Location "C:\Data\Files\"
$Files = Get-ChildItem File*.txt
$Final = ForEach ($File in $Files){
    $Content = Get-Content $File
    $Prefix = $Content[0].Substring(1,3)
    For ($i = 1;$i -lt $Content.Length-1;$i++){
         "{0}{1}" -f $Prefix,$Content[$i]
    } 
} 
$Final | Set-Content Final.txt

> gc .\Final.txt
bc1data1
bc1data2
fg4data3
fg4data4
ij7data5
ij7data6

Versão 2lida com arquivos grandes

## Q:\Test\2017\08\25\SU_1244148_2.ps1
#Set-Location "C:\Data\Files\"

$Files = (Get-ChildItem File*.txt|Sort)
$Final = '.\Final.txt'

## As we append to $Final initially clear
If (Test-Path $Final){Remove-Item $Final}

ForEach ($File in $Files){
    $Reader = [IO.File]::OpenText($File)
    $Header = $Reader.ReadLine()
    $Prefix = $Header.SubString(1,3)
    $Line = $Reader.ReadLine()
    while ($Reader.Peek() -ge 0) {
        $Prefix+$Line| Out-File $Final -Append
        $Line = $Reader.ReadLine()
    }
    $Reader.Dispose()
} 

Código otimizado para não precisar testar o cabeçalho final.
O loop while imprime a linha anterior e lê a próxima desta forma, descartando a última linha.

informação relacionada