Search string Copy numbers at end

This topic contains 0 replies, has 1 voice, and was last updated by  Forums Archives 5 years, 7 months ago.

  • Author
    Posts
  • #5640

    by vanhoja at 2013-03-07 14:01:54

    Hello,

    I am trying to create a script that will read a particular file that starts with SO and contains text lets say something like SO784314.eif. I am wanting to search the file for a particular line HD_LOAD_ID_NUMBER=123456 where the number length can very. I am needing to take the number and add to another line HD_LOAD_ID_NUMBER= and add a -2 to the end of the numbers so something like this HD_LOAD_ID_NUMBER=123456-2. Is there a way I can do this.

    by vanhoja at 2013-03-07 14:03:06

    This is what I have so far:
    $Content = Get-Content c:\test\SO*.eif | Select-String "LMR" -Quiet

    if ($Content -eq 'True'){
    echo test
    $ConfigFiles=Get-ChildItem c:\test\SO*.eif -Recurse
    foreach ($file in $ConfigFiles)
    {
    (Get-Content $file.PSPath) |

    ForEach-Object {
    $_ -replace "HD_LOAD_ID_NUMBER=", "HD_LOAD_ID_NUMBER=Test"} |
    Set-Content $file.PSPath
    }

    }

    by vanhoja at 2013-03-07 20:37:12

    Ok code update I have it searching, finding the numbers but when it goes to add them to the other line it adds the numbers for each file such as 1234 4859 12312-3 code below:
    $Location = "c:\test\SO*.eif"
    $SearchStr = "LMR"
    $LoadID = "PRFX_DOC_NBR="
    $DocID = "HD_LOAD_ID_NUMBER="

    $Sel = Select-String -Pattern $SearchStr -Path $Location
    if($Sel -eq $null)
    {
    write-host "$Location does not contain $SearchStr"
    }
    Else
    {

    $Num = Select-String -Pattern '(?< =^PRFX_DOC_NBR=)\d+' -Path $Location |
    ForEach-Object {$_.Matches[0].Value}
    write-host ($LoadID+$Num)

    $NumIn = Select-String -Pattern '(?< =^HD_LOAD_ID_NUMBER=)\d+' -Path $Location |
    ForEach-Object {$_.Matches[0].Value}

    $FileEdt = ("$DocID"+$Num +"-2")

    $ConfigFiles=Get-ChildItem $Location -Recurse
    foreach ($Sel in $ConfigFiles)
    {
    (Get-Content $Sel.PSPath) |

    ForEach-Object {
    $_ -replace "$DocID", "$FileEdt"} |
    Set-Content $Sel.PSPath
    }
    }

    by mjolinor at 2013-03-08 06:26:56

    Your code is a little hard to follow not knowing all the details of your file system, but based on your original description of the objective I came up with this using some test data:

    $file = 'c:\testfiles\SO784314.eif'
    (get-content $file) |
    foreach {
    [regex]::Replace($_,'(HD_LOAD_ID_NUMBER=\d+)',{"$args`n$args-2"})
    }

    by DonJ at 2013-03-08 06:30:29

    Vanhoja, please consider using the CODE button to format your code – that'll help make it easier for folks to read. There are additional tips at the top of this screen.

    by vanhoja at 2013-03-08 06:53:36

    im sorry, will try and do better. for a test file the data in it will be(actual file will have more):
    LMR
    PRFX_DOC_NBR=63190
    HD_LOAD_ID_NUMBER=

    What the code I am trying to write will check the files for any containing LMR and then get the PRFX_Doc number, in this case 63190. Then it will add the number along with -2 (63190-2) to the end of the HD_Load line. Right now the code I wrote reads all the files and gets all the doc numbers place the numbers together with a -2 at the end (HD_LOAD_ID_NUMBER= 9123 45698 63190-2) and does this to all 3 test files even though one does not have LMR. Reposting code using code button:

    $Location = "c:\test\SO*.eif"
    $SearchStr = "LMR"
    $LoadID = "PRFX_DOC_NBR="
    $DocID = "HD_LOAD_ID_NUMBER="

    $Sel = Select-String -Pattern $SearchStr -Path $Location
    if($Sel -eq $null)
    {
    write-host "$Location does not contain $SearchStr"
    }
    Else
    {

    $Num = Select-String -Pattern '(?< =^PRFX_DOC_NBR=)\d+' -Path $Location |
    ForEach-Object {$_.Matches[0].Value}
    write-host ($LoadID+$Num)

    $NumIn = Select-String -Pattern '(?< =^HD_LOAD_ID_NUMBER=)\d+' -Path $Location |
    ForEach-Object {$_.Matches[0].Value}

    $FileEdt = ("$DocID"+$Num +"-2")

    $ConfigFiles=Get-ChildItem $Location -Recurse
    foreach ($Sel in $ConfigFiles)
    {
    (Get-Content $Sel.PSPath) |

    ForEach-Object {
    $_ -replace "$DocID", "$FileEdt"} |
    Set-Content $Sel.PSPath
    }
    }

    by mjolinor at 2013-03-08 06:58:37

    Okay, that's a different scenario than I first undertood the problem to be. Let me work on that for a bit.

    by mjolinor at 2013-03-08 08:09:54

    Using this:
    $SearchStr = "LMR"
    $LoadID = "PRFX_DOC_NBR="
    $DocID = "HD_LOAD_ID_NUMBER="

    $text = @'
    some stuff
    LMR
    PRFX_DOC_NBR=63190
    HD_LOAD_ID_NUMBER=
    some other stuff
    LMR
    PRFX_DOC_NBR=63191
    HD_LOAD_ID_NUMBER=
    still more stuff
    '@

    $file = 'c:\testfiles\SO784314.eif'

    $text | set-content $file

    $regex = @"
    (?ms)$SearchStr
    $LoadID(\d+)
    $DocID
    "@

    ([IO.File]::ReadAllText($file)) -replace $regex,'$0$1-2'

    I get this:

    some stuff
    LMR
    PRFX_DOC_NBR=63190
    HD_LOAD_ID_NUMBER=63190-2
    some other stuff
    LMR
    PRFX_DOC_NBR=63191
    HD_LOAD_ID_NUMBER=63191-2
    still more stuff

    by vanhoja at 2013-03-08 08:58:08

    If I am reading it right you are hard coding in the code below and then it changes in the file. The problem is the document number will change each time so it can not be hard coded and there can be multiple .eif files in folder location.
    $text = @'
    some stuff
    LMR
    PRFX_DOC_NBR=63190
    HD_LOAD_ID_NUMBER=
    some other stuff
    LMR
    PRFX_DOC_NBR=63191
    HD_LOAD_ID_NUMBER=
    still more stuff
    '@

    by mjolinor at 2013-03-08 09:25:50

    All that's doing is creating a sample data file to test the script. Replace that sample data file with one of your production files and see if you get the expected results.

    Use just this much, and replace the path in $file with the path to one of your files:

    $file = 'c:\testfiles\SO784314.eif'

    $SearchStr = "LMR"
    $LoadID = "PRFX_DOC_NBR="
    $DocID = "HD_LOAD_ID_NUMBER="

    $regex = @"
    (?ms)$SearchStr
    $LoadID(\d+)
    $DocID
    "@

    ([IO.File]::ReadAllText($file)) -replace $regex,'$0$1-2'

    by vanhoja at 2013-03-08 10:09:40

    the file displays the data correctly in console if it only has those 3 lines but does not update actual file. Now when I have it point to an actual production file it does not work.

    by mjolinor at 2013-03-08 10:33:01

    It wasn't supposed to update the file. I'm just trying to produce a method that produces the correct data. We can worry about where it gets written to after we get it doing that much right.

    If it works with the sample data, but does not work with a production file, then then the sample data is not representative of the production data. Not having the prodcution files, I cannot say what's different. Only you can do that.

    by vanhoja at 2013-03-08 11:00:43

    ok, was just thrown off since it did edit the file in the earlier edition. The doc number and load id is the same format in file but can show up in different locations. LMR is only at end of string and the begging can be different.

    by mjolinor at 2013-03-08 11:06:24

    Can you post sample data from the producion file that could be used for testing?

    by vanhoja at 2013-03-08 11:12:35

    here is part of the file I just copied the part that had all 3 variables the file goes longer and it does not always appear in same line:

    RECORD_TYPE=PRFX
    PRFX_CO_ID=NS
    PRFX_EXT_PARTNER=NS
    PRFX_DOC_TYPE=Shipment
    PRFX_DOC_NBR=53190
    PRFX_TRANS_DIR=I
    PRFX_DATE=2013-03-06
    PRFX_TIME=08:37:28
    PRFX_CONTROL_NBR=NSP-63190-G0RF
    RECORD_TYPE=SO_ID
    HD_USER_ID=username
    HD_SO_SHPCMP_ID=NS
    HD_SO_SHPWHS_ID=LMR
    HD_LOAD_ID_NUMBER=

    by mjolinor at 2013-03-09 20:19:37

    What do you want the result from the script to look like, given that input?

    by vanhoja at 2013-03-09 20:29:54

    here is how the output should look like after updating the file, it needs to only do it to the files with LMR in it, basically it needs to take PRFX_DOC_NBR number append it to HD_LOAD_ID_NUMBER with a -2 and to add 01 to PRFX_CONTROL_NBR=NSP-63190-G0RF:
    RECORD_TYPE=PRFX
    PRFX_CO_ID=NS
    PRFX_EXT_PARTNER=NS
    PRFX_DOC_TYPE=Shipment
    PRFX_DOC_NBR=53190
    PRFX_TRANS_DIR=I
    PRFX_DATE=2013-03-06
    PRFX_TIME=08:37:28
    PRFX_CONTROL_NBR=01NSP-63190-G0RF
    RECORD_TYPE=SO_ID
    HD_USER_ID=username
    HD_SO_SHPCMP_ID=NS
    HD_SO_SHPWHS_ID=LMR
    HD_LOAD_ID_NUMBER=53190-2

    by mjolinor at 2013-03-09 21:58:45

    Okay, is this any closer?

    foreach ($file in (Get-ChildItem c:\test\SO*.eif | select -ExpandProperty fullname))
    {
    if (Select-String -Path $file -Pattern "LMR" -Quiet)
    {
    ( Get-Content $file) |
    foreach {

    switch -Regex ($_)
    {
    'PRFX_DOC_NBR=\d+' {$PrfDocNbr = $_ -replace '^\D+(\d+)','$1';$_}

    'HD_LOAD_ID_NUMBER=' {"$_$PrfDocNbr-2"}

    Default {$_}
    }

    } | Set-Content $file
    }
    }

    Edit – removed an extraneous pipe.

    by vanhoja at 2013-03-10 20:38:55

    Well when I try and run it I get the below errors, I have reboot just to make sure nothing had them open on computer.

    Set-Content : The process cannot access the file 'C:\test\SO64201.eif' because it is being used by another process.
    At C:\scripts\PSOtest.ps1:18 char:24
    + } | Set-Content < <<< $file
    + CategoryInfo : NotSpecified: (:) [Set-Content], IOException
    + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

    Set-Content : The process cannot access the file 'C:\test\SOtestNO.eif' because it is being used by another process.
    At C:\scripts\PSOtest.ps1:18 char:24
    + } | Set-Content < <<< $file
    + CategoryInfo : NotSpecified: (:) [Set-Content], IOException
    + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

    by mjolinor at 2013-03-10 20:44:41

    I made and edit to the script. See if that stops the errors.

    by vanhoja at 2013-03-10 20:46:46

    lol I had made that change myself after a quick search, it does work now. Just got to figure out/add updating the line from PRFX_CONTROL_NBR=NSP-63190-G0RF to PRFX_CONTROL_NBR=01NSP-63190-G0RF

    by MasterOfTheHat at 2013-03-11 13:21:25

    I took mjolinar's script and modified it to add your "01" to the PRFX_CONTROL_NBR, protect against adding a newline after the last line of the file (Set-Content does this by design), and get rid of the regex stuff (just because I don't like it and the .NET substring function is easier for me to understand). Also added break statements in the switch and tweaked the syntax to use ForEach-Object instead of the .NET foreach.
    [code2=powershell]Get-ChildItem c:\temp\SO*.eif | Select-Object -ExpandProperty fullname | ForEach-Object {
    if (Select-String -Path $_ -Pattern "LMR" -Quiet)
    {
    $str = ""
    ( Get-Content $_ ) |
    ForEach-Object {
    if ($str -ne "")
    {
    $str += "`n"
    }
    switch -Regex ($_)
    {
    'PRFX_DOC_NBR=\d+' {
    $PrfDocNbr = $_.substring($_.IndexOf("=")+1)
    $str += $_
    break;
    }
    'PRFX_CONTROL_NBR=*' {
    $str += "PRFX_CONTROL_NBR=01$($_.substring($_.IndexOf("=")+1))"
    }
    'HD_LOAD_ID_NUMBER=' {
    $str += "HD_LOAD_ID_NUMBER=$PrfDocNbr-2"
    break;
    }
    Default {
    $str += $_
    break;
    }
    }
    }
    [io.file]::WriteAllText($_, $str)
    }
    }[/code2]

    It turns this file:
    RECORD_TYPE=PRFX
    PRFX_CO_ID=NS
    PRFX_EXT_PARTNER=NS
    PRFX_DOC_TYPE=Shipment
    PRFX_DOC_NBR=53190
    PRFX_TRANS_DIR=I
    PRFX_DATE=2013-03-06
    PRFX_TIME=08:37:28
    PRFX_CONTROL_NBR=NSP-63190-G0RF
    RECORD_TYPE=SO_ID
    HD_USER_ID=username
    HD_SO_SHPCMP_ID=NS
    HD_SO_SHPWHS_ID=LMR
    HD_LOAD_ID_NUMBER=

    into this one:
    RECORD_TYPE=PRFX
    PRFX_CO_ID=NS
    PRFX_EXT_PARTNER=NS
    PRFX_DOC_TYPE=Shipment
    PRFX_DOC_NBR=53190
    PRFX_TRANS_DIR=I
    PRFX_DATE=2013-03-06
    PRFX_TIME=08:37:28
    PRFX_CONTROL_NBR=01NSP-63190-G0RF
    RECORD_TYPE=SO_ID
    HD_USER_ID=username
    HD_SO_SHPCMP_ID=NS
    HD_SO_SHPWHS_ID=LMR
    HD_LOAD_ID_NUMBER=53190-2

    by mjolinor at 2013-03-11 13:47:10

    If you'e going to "get rid of the regex" you should probably change the switch type to -Wildcard, and use an * instead of (/d+) in the first test.

    As it stands, you're using a Regex switch with a mixture of wildcard and regex test patterns.

    by vanhoja at 2013-03-11 13:48:46

    That worked perfectly thank you both, being so new to powershell it was driving me crazy.

    by mjolinor at 2013-03-11 13:50:31

    Do you understand it well enough to reproduce it for different data next time?

    by vanhoja at 2013-03-11 14:01:41

    I can read through it and see what it does for the most part but since I don't know it all yet parts I don't understand but know what the output does.

    by mjolinor at 2013-03-11 14:13:26

    I'd advise going through that and finding / reading the full help or about_ on anyting you don't understand.

    Come back and start a new thread with questions about anything you can't find the help on, or don't understand after reading the help.

    by vanhoja at 2013-03-11 14:17:44

    ok, thanks, I have all ready printed off the cheat shits provided in the forum but will run the help command to get some better understanding.

    by MasterOfTheHat at 2013-03-11 14:20:11

    [quote="mjolinor"]If you'e going to "get rid of the regex" you should probably change the switch type to -Wildcard, and use an * instead of (/d+) in the first test.

    As it stands, you're using a Regex switch with a mixture of wildcard and regex test patterns.[/quote]
    Gah! Nice catch, mjolinor. That's what I get for copying and pasting.

    And he's absolutely right. Read the help texts and ask questions!

You must be logged in to reply to this topic.