Search code examples
powershellfilepowershell-4.0

How to update column values in all lines in a text file using Powershell?


I have a text file that has 1000's of lines. And each lines has elements that are separated by tilde(~) delimiter. Now, i want to just change the first column value numbers to a Random/Unique number, i.e 34324242342333. It is of 15 chars length. But this is not working.

34324242342333~22~BB74~001~ 
34656453535353~22~C23~001~ 
00900900900889~22~N99~001~ 
97002021207021~22~F22~001~ 
23423432423421~22~V99~001~ 

Powershell code:

 $FileContent = Get-Content -Path C:\TestFiles\DummyData1.txt
        foreach ($Row in $FileContent) {
         $RandomNumber= Get-Random -Minimum 111111111111111 -Maximum 999999999999999
         $fields =  $Row.Split("~")
         $fields[0] =  $RandomNumber
         $fields -join '~' 
        }  Set-Content | C:\TestFiles\DummyDataUpdated.txt   
       

Solution

  • Unfortunately PowerShell doesn't permit piping the output of a foreach statement directly. To make your existing code working with the least amount of changes, wrap the foreach statement in a scriptblock:

    $FileContent = Get-Content -Path C:\TestFiles\DummyData1.txt
    
    # Wrap foreach in a scriptblock to be able to pipe it to Set-Content
    & {
        foreach ($Row in $FileContent) {
             $RandomNumber= Get-Random -Minimum 111111111111111 -Maximum 999999999999999
             $fields =  $Row.Split("~")
             $fields[0] =  $RandomNumber
             $fields -join '~' 
        }  
    } | Set-Content C:\TestFiles\DummyDataUpdated.txt  
    

    Here & {…} defines a scriptblock and immediately executes it, using the call operator &.

    Also I've fixed the typo in the Set-Content call (there should be no pipe symbol before the file path argument).


    As an alternative, streamlined solution, get rid of the temporary variable $fileContent and use a single pipeline to avoid the foreach statement:

    Get-Content -Path C:\TestFiles\DummyData1.txt | ForEach-Object {
        $RandomNumber= Get-Random -Minimum 111111111111111 -Maximum 999999999999999
        $fields =  $_.Split("~")
        $fields[0] =  $RandomNumber
        $fields -join '~' 
    } | Set-Content C:\TestFiles\DummyDataUpdated.txt   
    

    The variable $row has been replaced by automatic variable $_ which denotes the current element processed by the pipeline.