Empty Coder
Empty Coder

Reputation: 589

Insert comma before a value if it is blank

Below is the data I have

-Ignored:31,Modified,src,data,all,*file,MINOSFIC/UTMNUP10
-Ignored:33,Modified,src,&,tgt,data,all,*file,MINOSFIC/UVEGAP10
-Ignored:92,Synchro,is,running,*file,MINOSFIC/VM010P50
-Ignored:01,Object,hold,(synchro),*file,MINOSFIC/VM010U51

here I am parsing the data and keeping in csv for 1st and 2nd line it is working but when it is coming to 3rd and 4th line, it is pushing the column value one forward as there is no data before *file

Please let me know how to handle this. how to insert a comma before *file if there is not entry (like for first 2 line it is all)

$allIGfiles = Get-ChildItem -Path 'C:\LG2' -Recurse -Filter "*LG_VFN*"

foreach($file in $allIGfiles)
{
    $filename = $file.FullName

$data = Get-Content $filename | Select -SkipLast 1
$Lines = @()
foreach ($line in $data){ 
if($line -match "Ignored")
{
    $Lines+=$line
}
}

$NewLines = @($Lines | % { ($_  -replace "\s{2,}",",") -replace "(\d) ", '$1,'} )
$NewLines | Export-Csv 'c:\file.csv' -append -NoTypeInformation

Original data

-Ignored:31 Modified src data        all *file   MINOSFIC/UTMNUP10
-Ignored:33 Modified src & tgt data  all *file   MINOSFIC/UVEGAP10
-Ignored:92 Synchro is running           *file   MINOSFIC/VM010P50
-Ignored:01 Object hold (synchro)        *file   MINOSFIC/VM010U51

Update:

I am now getting the data like below but when i am trying to put it in csv it is only writing numbers to the file

-Ignored:31,Modified src data,all *file,MINOSFIC/UTMNUP10
-Ignored:33,Modified src & tgt data,all *file,MINOSFIC/UVEGAP10
-Ignored:92,Synchro is running,*file,MINOSFIC/VM010P50
-Ignored:01,Object hold (synchro),*file,MINOSFIC/VM010U51
-Ignored:01,Object hold (synchro),*file,MINOSFIC/VM010U52
-Ignored:01,Object hold (synchro),*file,MINOSFIC/VM010U53
-Ignored:01,Object hold (synchro),*file,MINOSFIC/VM010U54

Data with other code

 Object OK            (partial)      97% *file   MINOSFIC/VM011P10
-Ignored:18 Object hold                  *file   MINOSFIC/VM011P50
 Object OK            (partial)      78% *file   MINOSFIC/VM800P30
*Error:  09 Diff. Creation date      *file   MINOSSVG/S100000702
*Error:  09 Diff. Creation date      *file   MINOSSVG/S100000805
-Ignored:18 Object hold                  *file   MINOSSVG/S100001154
*Error:  09 Diff. Creation date      *file   MINOSSVG/S100001227

Upvotes: 0

Views: 54

Answers (2)

Theo
Theo

Reputation: 61253

You could do this by using a regex that at first ignores the all value, but when constructing the comma separated new string, this will be inserted when found:

Read the file as string array

$data = Get-Content -Path $filename

I'm faking that by using a Here-String below:

$data = @"
-Ignored:31 Modified src data        all *file   MINOSFIC/UTMNUP10
-Ignored:33 Modified src & tgt data  all *file   MINOSFIC/UVEGAP10
-Ignored:92 Synchro is running           *file   MINOSFIC/VM010P50
-Ignored:01 Object hold (synchro)        *file   MINOSFIC/VM010U51
"@ -split '\r?\n'

$result = foreach ($line in $data) {
    if ($line -match '^(-Ignored:\d+)\s+(.+)\s+(\*file)\s+(.*)') {
        '{0},{1},{2},{3},{4}' -f $matches[1], 
                                 ($matches[2] -replace 'all$').Trim(),
                                 ($matches[2] -split '\s{2,}')[-1],
                                 $matches[3], 
                                 $matches[4]

    }
}

# output to console screen
$result

# write to file
$result | Set-Content -Path 'X:\TheNewFile.txt'

Output:

-Ignored:31,Modified src data,all,*file,MINOSFIC/UTMNUP10
-Ignored:33,Modified src & tgt data,all,*file,MINOSFIC/UVEGAP10
-Ignored:92,Synchro is running,,*file,MINOSFIC/VM010P50
-Ignored:01,Object hold (synchro),,*file,MINOSFIC/VM010U51

To also do this with *Error.. lines as in your updated example, change the line

if ($line -match '^(-Ignored:\d+)\s+(.+)\s+(\*file)\s+(.*)') {

into

if ($line -match '^((?:-Ignored|\*Error):\s*\d+)\s+(.+)\s+(\*file)\s+(.*)') {

Regex details:

^                        Assert position at the beginning of a line (at beginning of the string or after a line break character)
(                        Match the regular expression below and capture its match into backreference number 1
   (?:                   Match the regular expression below
                         Match either the regular expression below (attempting the next alternative only if this one fails)
         -Ignored        Match the characters “-Ignored” literally
      |                  Or match regular expression number 2 below (the entire group fails if this one fails to match)
         \*              Match the character “*” literally
         Error           Match the characters “Error” literally
   )                    
   :                     Match the character “:” literally
   \s                    Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      *                  Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   \d                    Match a single digit 0..9
      +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)                       
\s                       Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                     Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(                        Match the regular expression below and capture its match into backreference number 2
   .                     Match any single character that is not a line break character
      +                  Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)                       
\s                       Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                     Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(                        Match the regular expression below and capture its match into backreference number 3
   \*                    Match the character “*” literally
   file                  Match the characters “file” literally
)                       
\s                       Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                     Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(                        Match the regular expression below and capture its match into backreference number 4
   .                     Match any single character that is not a line break character
      *                  Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)

Upvotes: 1

vonPryz
vonPryz

Reputation: 24091

One approach is to first replace two consecutive spaces with a comma. Then replace digit followed with a space with the same digit via capture group and a comma. Like so,

$data=@(
 '-Ignored:31 Modified src data        all *file   MINOSFIC/UTMNUP10',
 '-Ignored:33 Modified src & tgt data  all *file   MINOSFIC/UVEGAP10',
 '-Ignored:92 Synchro is running           *file   MINOSFIC/VM010P50',
 '-Ignored:01 Object hold (synchro)        *file   MINOSFIC/VM010U51')

$data | % { ($_  -replace "\s{2,}",",") -replace "(\d) ", '$1,'}
-Ignored:31,Modified src data,all *file,MINOSFIC/UTMNUP10
-Ignored:33,Modified src & tgt data,all *file,MINOSFIC/UVEGAP10
-Ignored:92,Synchro is running,*file,MINOSFIC/VM010P50
-Ignored:01,Object hold (synchro),*file,MINOSFIC/VM010U51

This would get all *file in same column as *file. Should that not be enough, use ConvertFrom-String or do another replacement to introduce the missing column. As of how, you probably need to calculate how many commas there are and deduct from that if the column is needed.

Upvotes: 1

Related Questions