-2

i have a ini file:

number=1
problem=4
issue=2
test=7

number=2
problem=5
issue=3
test=8

with duplicate keys but different values.

How can I delete every doubled key with powershell?

My final ini file should look like this:

number=1
problem=4
issue=2
test=7

Thank you!

UPDATE: 09/10/2018 (I was in holidays sorry)

I finally made it! It works absolutely perfect, thank you guys and special thanks to @Richard Siddaway

@Theo you are right. I missed my [sections] and I added them and a further part for my second program that should be able to read the ini file

So this is my code:

#merge two files
$files = Get-ChildItem "D:\all"
foreach ($file in $files) {

$name = dir $file.FullName | select -ExpandProperty Name
$ReferenceObject = Get-Content D:\File.ini
$DifferenceObject = Get-Content $file.FullName
Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -PassThru | Out-File ('D:\output\' + $name)

# filter Date an Number
$fileContent = Get-Content ('D:\output\' + $name)
# iterate over lines
foreach($line in $fileContent) {
    #add "=" to [section]
    if($line.StartsWith('[')) {
    $newline = ($line + '=')
    $newline | Add-Content ('D:\output2\' + $name)
    }
  # filter lines beginning with 'Date, ...'
    elseif((-not $line.StartsWith('Date')) -and (-not $line.StartsWith('Number')) -and (-not $line.StartsWith('Date2'))) {
    # output lines to new file
    $line | Add-Content ('D:\output2\' + $name)
  }
}

#remove duplicates
$fileContent = Get-Content ('D:\output2\' + $name)
$unqkeys = [ordered]@{}
foreach ($line in $fileContent){

    if ($line -ne '') {
    $a = $line -split '='

    if (-not $unqkeys[$($a[0].Trim())]){
      $unqkeys += @{$a[0].Trim() = $a[1].Trim()}
    }
  }
}
$unqkeys.GetEnumerator() | 
foreach {
   Out-File -FilePath ('D:\output3\' + $name) -InputObject "$($_.key)=$($_.value)" -Append 
}


# add file location to [section]
$fileContent = Get-Content ('D:\output3\' + $name)
foreach($line in $fileContent) {
  # filter for section
  if($line.StartsWith('[')) {
    # output lines to new file 
    $newline = $line -replace "[[]", "|" -replace "]=", "]"
    $linemodif = ("[C:\mypath\File.ini" + $newline)
    $linemodif | Add-Content ('D:\output4\' + $name)
  }else {
    $line | Add-Content ('D:\output4\' + $name)
  }
}
}

#Move ouput to solution
Get-ChildItem -Path "D:\output4\*.*" -Recurse | Move-Item -Destination "D:\solution" -force

#delete every single output
Remove-Item -Path D:\output\*.*
Remove-Item -Path D:\output2\*.*
Remove-Item -Path D:\output3\*.*
Remove-Item -Path D:\output4\*.*

This was my ini-file after the merge:

[SECTION1]
Tester=5
Magnet=2
Number=3459353484
Date=01/01/2018 11:00:00
Problem=
Issue=
[SECTION2]
Progress=0
Tester=4
Magnet=1
Number=0
Date=01/01/1999

And this is my result:

[C:\mypath\File.ini|SECTION1]
Tester=5
Magnet=2
Problem=
Issue=
[C:\mypath\File.ini|SECTION2]
Progress=0

As you can see it still looks like someone "just pasted together some random snippets" as @Paxz said. I'm finished and totally happy with it because it does what its meant to be, but I well know my script is not very clean neither a good solution. Especially with my outputs :/ maybe someone has hints for me to improve for the next time? Maybe I can somehow hold every output in an variable? And I added an '=' to my sections to be able to use Richards script...

  • 2
    What have you tried so far? We'll be happy to help you to debug your script but won't write it for you from scratch. – TobyU Aug 20 '18 at 13:26
  • 1
    What have you tried so far? Where did you fail? We are not here to write code for you. Pleasee try to offer a [mcve]. – Paxz Aug 20 '18 at 13:26
  • 1
    sure, give me a second – John Vision Aug 20 '18 at 13:28
  • I marked it as correct ty. And I added my code. Do you know a command or something to delete double keys? – John Vision Aug 20 '18 at 13:42
  • 1
    Well your Code looks like you just pasted together some random snippets from earlier answers.. but all-in-all it pretty much looks like a XY-Problem (http://xyproblem.info/). Please try to explain what you actually try to achieve and try to explain your szenario, why do you want to delete the duplicate lines of your file? Why does your .ini file even have duplicated lines? – Paxz Aug 20 '18 at 13:47
  • Yes it actually is. I'm a newbie and I have absolutely no idea how to proceed. I'm not an idiot. What do you not understand in my question? Everything else is here: https://stackoverflow.com/questions/51898328/delete-everything-after-keyword which didn't helped me a lot so it lead me to this question. It's just that simple: Is there something to check double keys or not? I didn't found anything... – John Vision Aug 20 '18 at 13:59
  • Yes there is. There are many ways. But lets keep this a learning experience: You could for example import your .ini file into an ps-object just by using `import-csv -path .\file.ini -header "title","num"` and go on with `Group-Object` to sort the entries (i did this right now). Another way could be `select-string` with regex-patterns and a simple `Where-Object` query. Try your best, edit your question and try to solve the problem. When you achieve something that is close i can still help you fix small bugs :). – Paxz Aug 20 '18 at 14:50
  • ..it all starts with a file called .ini which really is NOT an ini file. It just looks like that on first glance, but since it is missing the `[SECTIONS]` to group the data, you are bound to have duplicate values. See [INI format specification](https://github.com/SemaiCZE/inicpp/wiki/INI-format-specification) – Theo Aug 20 '18 at 18:48
  • You could load it all into a variable. Then grab unique name values. Then search for the first instance of each one and place only that value and name into the file. (just the logic here) – Robert Cotterman Aug 21 '18 at 02:31
  • I finished my script, not very clean but it works thank you. What do you think? @Paxz – John Vision Sep 10 '18 at 13:07

1 Answers1

0

Try this

if (Test-Path -Path c:\test\new.ini) {
  Remove-Item -Path c:\test\new.ini
}

$unqkeys = [ordered]@{}


$lines = Get-Content -Path C:\test\t1.ini 
foreach ($line in $lines){
  if ($line -ne '') {
    $a = $line -split '='

    if (-not $unqkeys[$($a[0].Trim())]){
      $unqkeys += @{$a[0].Trim() = $a[1].Trim()}
    }
  }
}

$unqkeys.GetEnumerator() | 
foreach {
   Out-File -FilePath C:\test\new.ini -InputObject "$($_.key)=$($_.value)" -Append 
}


Get-Content -Path C:\test\new.ini

I'm using an ordered hash table to hold the unique keys - first one found in the file. At the end write the data back to a new file. You should be able to modify this to meet your needs