简体   繁体   中英

How to replace the second occurrence of a character in powershell?

I'm really struggling with a task that is probably easier than I image it.

I have a file with a lot of lines:

eg

"numbers TG alongstring" 
"numbers 100 alongstring" 
"numbers 120 alongstring" 
"numbers AF alongstring" 
"numbers 123 alongstring" 

I want to replace the second occurrence of (space) with (two spaces) so that the longstrings line up with each other. The strings that are 2 characters long are always numbers.

Something like this:

"numbers TG  alongstring" 
"numbers 100 alongstring" 
"numbers 120 alongstring" 
"numbers AF  alongstring" 
"numbers 123 alongstring" 

A thing to note is that the numbers at the beginning are unique along 4000 lines and the longstrings are also not the same length.

What I have so far:

foreach ($Line in $file) {
if ($Line[10] -eq " ") {
    $Line.Replace(" ", "  ")
    
    }

}

[10] is the index of the space I want to replace.

This replaces all the single spaces with double spaces I tried a lot of things but haven't had any luck so far.

Any help is greatly appreciated.

Replace (?m)(^[^\n\r ]* [^\n\r ]{2}) (it contains a trailing space) with $1 (it contains a double trailing space).

This regex replaces the second single-space occurrence with a double space only if it is preceded by two non-space characters.

  • (?m) is the multiline flag
  • ^ matches the beginning of the line (because of (?m) , otherwise it would metche the very beginning of the string)
  • [^\n\r ]* matches zero or more characters that are neither a space nor a new line
  • [^\n\r ]{2} matches exactly two characters that are neither a space nor a new line
  • (...) is a capturing group, and you refer to it with $1

See a demo here .

Among other solutions you could use

^((?:[^\n ]* (?! )){2})

And replace this with $1 .
See a demo on regex101.com .

Try testing the .LastIndexOf( ' ' ) return. if the last index of space is 10 you know you are missing a space. Then you can use the .Insert() method to add it in the same position.

Maybe something like:

foreach ($Line in $file) {
    if ($Line.LastindexOf( ' ' ) -eq 10 ) {
        $Line.Insert( 10, ' '  )
        }
    }

Something like this could work and you should be able to come up with a generalized pattern for a match criteria.

Get-Content $file | Foreach-Object {
    # matches <nonspaces><space><nonspaces><spaces><rest of string>
    if ($_ -match '^([^ ]+ \S+ +)(.*)$') {
        # $matches.1 is everything matching in the first ()
        # $matches.2 is everything matching in the second ()
        # Assumes alongstring desirably lines up at position 13 starting from 0. Change 13 to the appropriate number if necessary
        ($matches.1).PadRight(13,' ') + $matches.2
    } else {
        $_ 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM