2
votes

Comment exporter une chaîne de plusieurs lignes vers du texte sur une seule ligne

J'ai un fichier texte "c: \ zz.txt" dont un extrait est le suivant:

ABSA ALL ROUNDER FoF, UT-ABSAAG, 20190215    393.83    393.83   0.00
ABSA BALANCED FUND, UT-ABSABA, 20190215    432.28    432.28   0.00
COMMUNITY GILT, UT-COM-G, 20190215    151.21    151.21   8.59

Je voudrais l'exporter dans un fichier .TXT au format suivant:

clear-Host
get-content -raw "c:\zz.txt" | % { $_ -replace '(#N)',"`r`n"} |% { $_ -replace '(#D|#P)',','}|Set-Content ZZ1.txt

Mon code ci-dessous

UT_Name,UT_Code,Date,Value1,Value2,Vol
ABSA ALL ROUNDER FoF,UT-ABSAAG,20190215,393.83,393.83,0
ABSA BALANCED FUND,UT-ABSABA,20190215,432.28,432.28,0
COMMUNITY GILT,UT-COM-G,20190215,151.21,151.21,8.59

Sortie:

#N ABSA ALL ROUNDER FoF
#D UT-ABSAAG
#P 20190215    393.83    393.83   0.00

#N ABSA BALANCED FUND
#D UT-ABSABA
#P 20190215    432.28    432.28   0.00

#N COMMUNITY GILT
#D UT-COM-G
#P 20190215    151.21    151.21   8.59

Problème: Le problème se trouve être que l'ensemble de données "#P" dans l'ensemble de données d'origine est de longueur fixe, ce qui signifie que je ne peux pas simplement remplacer tous les espaces, par des virgules car cela affectera également les noms de champ "#N" et "#D" au-dessus desquels je ne veut pas affecter.

Comment remplacer sélectivement les espaces blancs?


0 commentaires

3 Réponses :


1
votes

cela utilise des groupes de capture nommés pour obtenir les éléments, puis les exporte vers un fichier CSV.

"UT_Name","UT_Code","Date","Value1","Value2","Vol"
"ABSA ALL ROUNDER FoF","UT-ABSAAG","20190215","393.83","393.83","0.00"
"ABSA BALANCED FUND","UT-ABSABA","20190215","432.28","432.28","0.00"
"COMMUNITY GILT","UT-COM-G","20190215","151.21","151.21","8.59"

contenu du fichier CSV ...

# fake reading in a raw text file
#    in real life, use Get-Content -Raw
$InStuff = @'
#N ABSA ALL ROUNDER FoF
#D UT-ABSAAG
#P 20190215    393.83    393.83   0.00

#N ABSA BALANCED FUND
#D UT-ABSABA
#P 20190215    432.28    432.28   0.00

#N COMMUNITY GILT
#D UT-COM-G
#P 20190215    151.21    151.21   8.59
'@

# split into blocks, trim unwanted whitespace, filter out the blank block
$SplitInStuff = ($InStuff -split '#N').Trim().Where({$_})

$Results = foreach ($SIS_Item in $SplitInStuff)
    {
    $Null = $SIS_Item -match '(?sm)(?<UT_Name>^.+$).*#D (?<UT_Code>.+).*#P (?<Date>\d+)\s+(?<Value1>[0-9.]+)\s+(?<Value2>[0-9.]+)\s+(?<Vol>[0-9.]+)'
    [PSCustomObject]@{
        # the ".Trim()" was needed to remove leftover EOL/NewLine/space chars
        UT_Name = $Matches.UT_Name.Trim()
        UT_Code = $Matches.UT_Code.Trim()
        Date = $Matches.Date.Trim()
        Value1 = $Matches.Value1.Trim()
        Value2 = $Matches.Value2.Trim()
        Vol = $Matches.Vol.Trim()
        }
    }

$Results |
    Export-Csv -LiteralPath "$env:TEMP\milkywaypizza_ProductInfo.csv" -NoTypeInformation


0 commentaires

1
votes

Autre méthode:

$Data = @'
#N ABSA ALL ROUNDER FoF
#D UT-ABSAAG
#P 20190215    393.83    393.83   0.00

#N ABSA BALANCED FUND
#D UT-ABSABA
#P 20190215    432.28    432.28   0.00

#N COMMUNITY GILT
#D UT-COM-G
#P 2019021    151.21    151.21   8.59
'@

#template for learn schema
$template=@'
#N {Vol_ABSA_ALL_ROUNDER_FoF*:ABSA ALL ROUNDER FoF}
#D UT-{UT_Name:ABSAAG}
#P {Date:20190215}    {Value1:393.83}    {Value2:393.83}   {Vol:0.00}

#N {Vol_ABSA_ALL_ROUNDER_FoF*:ABSA ALL ROUNDER FoF 2}
#D UT-{UT_Name:ABSAAG2}
#P {Date:20190216}    {Value1:393.83}    {Value2:393.83}   {Vol:0.00}
'@

$Data | ConvertFrom-String -TemplateContent $template | export-csv "c:\temp\result.csv" -NoType


1 commentaires

Je pense qu'il est important d'ajouter la clause de non-responsabilité suivante chaque fois que ConvertFrom-String est utilisé: il fournit une analyse basée sur les séparateurs ainsi qu'une analyse basée sur l'heuristique basée sur des modèles contenant des exemples de valeurs. L'analyse basée sur les séparateurs applique des conversions de type automatiques que vous ne pouvez pas contrôler, et le langage du modèle est mal documenté, avec le comportement exact difficile à prévoir - il est préférable d'éviter complètement cette applet de commande. Notez également qu'il n'est pas disponible dans PowerShell Core .



1
votes

Comment remplacer sélectivement des séries de plusieurs caractères d'espaces?

Par exemple, en sélectionnant uniquement plusieurs espaces avec un quantificateur -replace "{2,}", ','

Le script suivant basé sur votre one liner:

> Get-Content .\ZZ1.txt
UT_Name,UT_Code,Date,Value1,Value2,Vol
ABSA ALL ROUNDER FoF,UT-ABSAAG,20190215,393.83,393.83,0.00
ABSA BALANCED FUND,UT-ABSABA,20190215,432.28,432.28,0.00
COMMUNITY GILT,UT-COM-G,20190215,151.21,151.21,8.59

génère cette sortie:

## Q:\Test\2019\03\28\SO_55387785.ps1
$FileIn = '.\zz.txt'
$FileOut= '.\zz1.txt'

 Set-Content $FileOut -Value "UT_Name,UT_Code,Date,Value1,Value2,Vol"
(Get-Content $FileIn -raw) -replace "(`r?`n)?#N " -replace "`r?`n(#D|#P) | {2,}",',' |
 Add-Content $FileOut


0 commentaires