locked
Search a string and remove set of lines from a text file RRS feed

  • Question

  • Hi I am new to PowerShell and very interested to learning J

    I need help form you all Scripting Guys! Im trying to create a PS script for modifying/updating a configuration file looks like as below

    .

    .   

            SERVICE_LEVEL = ""

             EXPANDED = "TRUE"

       END_NODE  

    NODE

             NODE_NAME = "am01"

             VERSION = ""

             CPU_TYPE = ""

             OS = ""        

             CONSOLE_REPOSITORY = "c:\tda\lux4"

             REMOTE_REPOSITORY = ""

             SAMPLING_INTERVAL = 0

             DATA_TRANSFER = 0

             DESCRIPTION = ""

             SYSTEM_NAME = "am01"

             INTERNET_ADDRESS = ""

             DATA_SOURCE = "Real-time"

             OUTSIDE_FIREWALL = 0

             SERVICE_LEVEL = ""

             EXPANDED = "TRUE"

      END_NODE

    NODE

             NODE_NAME = "am03"

             VERSION = ""

             CPU_TYPE = ""

             OS = ""        

             CONSOLE_REPOSITORY = "c:\tda\lux4"

             REMOTE_REPOSITORY = ""

             SAMPLING_INTERVAL = 0

             DATA_TRANSFER = 0

             DESCRIPTION = ""

             SYSTEM_NAME = "am03"

             INTERNET_ADDRESS = ""

             DATA_SOURCE = "Real-time"

             OUTSIDE_FIREWALL = 0

             SERVICE_LEVEL = ""

             EXPANDED = "TRUE"

       END_NODE

    NODE

             NODE_NAME = "am001"

             VERSION = ""

             CPU_TYPE = ""

             OS = ""

    .

    .

    .

    the requirements are..

    1.        I need to read the content of the file and search a string that is server name  (in this case “am01” )
    2.        And delete the set of lines only from the line NODE  to the line END_NODE  where the string "am01" is found  between these lines.
      • the server name "am01" contains only between the line NODE  to END_NODE  
    3.        then Save the file
    4.        then log the deleted content (lines) to a separate text file to ensure that what are the contents we have deleted.

    Could anyone have idea on this …

    Reply back if have any questions

    Thanks..

    Kanda.

    Tuesday, June 16, 2015 2:46 PM

Answers

  • Hi All, finally i have completed my PS script, i was quite busy with other tasks so it takes some time to complete.

    below is my script and it works as expected :) . thanks to Leif and Jrv and this forum.

    it will search a node from multiple plc files in given directory and take backup then remove it from a plc file (as explained  my previous post )then save it to same location.

    Please review and reply if you have better idea than me.

    $Console = Get-Content C:\temp\bpa.txt
    $Node = Get-Content C:\temp\node.txt
    $Removed,$NotFound = @()  
    foreach ($server in $console){  
     if (Test-Connection $server -Count 2 -Quiet) {
       foreach ($Srv in $Node) {  
        $findFile = Get-ChildItem -path "\\$server\d$\bmc\scripts\*.plc" | select-string -pattern "$Srv" | group path | % {$_.name} 
        $date = Get-Date -Format "dd-MM-yy mm,fff"
        $findFile | % { gci $_ } | % { Copy-Item $_ ("\\$server\D$\BMC\scripts\PlcBackup\"+$_.basename +"_$date") }
            if($findFile -eq $null)  {
                $NotFound += "Policy file not found for the Node $Srv" }
            else {         
              foreach ($plcfile in $findFile)    {           
                $file = Get-Content $plcfile -Raw
                $result = $file | Select-String -Pattern "(?smi)(\s+NODE\s+NODE_NAME = `"$Srv`".*?END_NODE)"
                $removed += $result.Matches.Value 
                $file -replace "(?smi)(\s+NODE\s+NODE_NAME = `"$Srv`".*?END_NODE)" | Out-File -FilePath $plcfile   
                 }
               }
       }
       $date = Get-Date -Format "d-MMM-yyyy hh,mm"
       $removed | Out-File -FilePath ("C:\temp\log\Removed contant"+" $date"+".txt")
       $NotFound | Out-File -FilePath "C:\temp\log\Node not found $date.txt"
       }
       else { Write-Host "The console $server is not reachable"}
    }


    Thanks, Kanda

    • Marked as answer by Kandaraj Friday, June 26, 2015 2:51 PM
    • Unmarked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Marked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Unmarked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Marked as answer by Bill_Stewart Friday, August 14, 2015 7:54 PM
    Friday, June 26, 2015 2:50 PM

All replies

  • What does your script look like so far? The purpose of this forum isn't to write scripts on request.

    Please read the following:


    -- Bill Stewart [Bill_Stewart]

    Tuesday, June 16, 2015 2:52 PM
  • Sorry Bill Stewart i did not read Posting guidelines and in not expecting full script 
    I am expecting ideas and help  so for my script as below very simple :) 

    $file = get-content C:\temp\config.txt 
    $file | select-string -pattern "am01"  -NotMatch | % {$_.Line} 
    ...
    I am struggling with above one
    it is deleted only the line where the search pattern is there.
    Wednesday, June 17, 2015 11:24 AM
  • Try this, but please back up your config file first.

    # Use -Raw to get entire content as one string. Requires PowerShell 3.0
    $file = Get-Content C:\temp\config.txt -Raw
    
    # Find node containing NODE_NAME am01
    $result = $file | Select-String -Pattern '(?smi)(NODE\s+NODE_NAME = "am01".*?END_NODE)'
    
    # Save node to new file named node.txt
    $result.Matches.Value | Out-File -FilePath C:\Temp\node.txt
    
    # Replace node with nothing and save to config.txt
    $file -replace '(?smi)(NODE\s+NODE_NAME = "am01".*?END_NODE)' | Out-File -FilePath C:\temp\config.txt

    Wednesday, June 17, 2015 9:30 PM
  • Wow... Great :)

    almost i got what I expected  Thanks  Leif-Arne

    can you please explain the below line in details ?

    '(?smi)(NODE\s+NODE_NAME = "am01".*?END_NODE)' 


    Thursday, June 18, 2015 2:08 PM
  • It's a Regular Expression.

    (?smi)
    This is Regular Expression Options.

    (NODE\s+NODE_NAME = "am01".*?END_NODE)
    This is the regular expression. It will match the word NODE followed by any white-space character (\s), one or more times (+). Next it will match the text NODE_NAME = "am01" followed by any character (.), zero or more times but as few times as possible (*?), until we find END_NODE.

    Please visit the two links in this post for more details.

    Thursday, June 18, 2015 6:47 PM
  • Hi Leif-Arne  thanks for details.

    How do i include powershell variable into Regex. i am trying to search more servers by foreach loop

    $srv = 'am01','am02','am03'

    '(?smi)(NODE\s+NODE_NAME = "$srv".*?END_NODE)' 

     but its not working i used " instated of  '  but no luck

    any help ? 


    Thanks, Kanda

    Friday, June 19, 2015 12:43 PM
  • "(?smi)(NODE\s+NODE_NAME = `"$srv`".*?END_NODE)"

    \_(ツ)_/

    Friday, June 19, 2015 12:47 PM
  • :) :) super i crossed one more milestone :)

    Thanks Jrv


    Thanks, Kanda


    • Edited by Kandaraj Friday, June 19, 2015 2:48 PM name change
    Friday, June 19, 2015 2:47 PM
  • Hi All, finally i have completed my PS script, i was quite busy with other tasks so it takes some time to complete.

    below is my script and it works as expected :) . thanks to Leif and Jrv and this forum.

    it will search a node from multiple plc files in given directory and take backup then remove it from a plc file (as explained  my previous post )then save it to same location.

    Please review and reply if you have better idea than me.

    $Console = Get-Content C:\temp\bpa.txt
    $Node = Get-Content C:\temp\node.txt
    $Removed,$NotFound = @()  
    foreach ($server in $console){  
     if (Test-Connection $server -Count 2 -Quiet) {
       foreach ($Srv in $Node) {  
        $findFile = Get-ChildItem -path "\\$server\d$\bmc\scripts\*.plc" | select-string -pattern "$Srv" | group path | % {$_.name} 
        $date = Get-Date -Format "dd-MM-yy mm,fff"
        $findFile | % { gci $_ } | % { Copy-Item $_ ("\\$server\D$\BMC\scripts\PlcBackup\"+$_.basename +"_$date") }
            if($findFile -eq $null)  {
                $NotFound += "Policy file not found for the Node $Srv" }
            else {         
              foreach ($plcfile in $findFile)    {           
                $file = Get-Content $plcfile -Raw
                $result = $file | Select-String -Pattern "(?smi)(\s+NODE\s+NODE_NAME = `"$Srv`".*?END_NODE)"
                $removed += $result.Matches.Value 
                $file -replace "(?smi)(\s+NODE\s+NODE_NAME = `"$Srv`".*?END_NODE)" | Out-File -FilePath $plcfile   
                 }
               }
       }
       $date = Get-Date -Format "d-MMM-yyyy hh,mm"
       $removed | Out-File -FilePath ("C:\temp\log\Removed contant"+" $date"+".txt")
       $NotFound | Out-File -FilePath "C:\temp\log\Node not found $date.txt"
       }
       else { Write-Host "The console $server is not reachable"}
    }


    Thanks, Kanda

    • Marked as answer by Kandaraj Friday, June 26, 2015 2:51 PM
    • Unmarked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Marked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Unmarked as answer by Kandaraj Friday, June 26, 2015 2:55 PM
    • Marked as answer by Bill_Stewart Friday, August 14, 2015 7:54 PM
    Friday, June 26, 2015 2:50 PM