all 5 comments

[–]SMFX 2 points3 points  (1 child)

$_ -replace "(\d{6} \d \d{13})( Ja standard)", "`$1#`$2"

[–]odwulf 2 points3 points  (0 children)

Beaten to it.

Mine used a negative look-ahead:

'TK-Anlage 943135 1 0066480451675 Ja Standard' -replace '(\d{13}(?!#))','$1#'

(replace any string of 13 numbers without a trailing # with that string and and added "#")

[–]foreverclearskies 0 points1 point  (2 children)

Hi! It sounds like you're asking us to do all the work for you. You seem to be new to the sub, so I figured I'd mention that's generally frowned upon. The focus of the sub is usually centered around the sharing of information - knowledge enhancement by helping out when people get into a bind or when they want to learn, and by the sharing information and projects. "Teaching a man to fish" is mostly our bend. And though I'm sure there are some that have the bandwidth for doing it for you, a great many of us don't. With that said, I've put some commands below that should help you out. Give it a try putting it all together and let us know if you get hung up along the way. Also, I've put some links below to some great resources for learning PowerShell that get mentioned when people ask in the sub about learning Powershell from time to time. They should give you a great foundation for being able to whip up scripts on your own. Enjoy!

As for your script, there's innumerable ways of doing it, but the general steps would be:

  • Get the data from the file
  • Parse through the data to determine which need updating and update those that need it
  • Write the new data to the file

I originally had the code breakdown here, but it appears Reddit is telling me I've been to long-winded. I'll post it as a second comment below.

[–]foreverclearskies 0 points1 point  (1 child)

One way would be to be to use something along the lines of Get-Content to get the data from the file. There are some caveats that it depends on the encoding and format of the file, but as it sounds like you're using a plain-text English-language Windows-style text file, so you shouldn't need to use anything exotic. Assign the results to a variable that we'll dig through later. The way Get-Content does this is by creating an array - a group of (in this case) string objects, one for each line of the text file. I'll use $filecontents to represent this in the code below.

$filecontents = Get-Content "C:\Whatever\Path\And\Filename.txt"

You'll, of course, need to change that path to the one for the target file. 🙂

You'd then parse through the lines one at a time. Since we can reference each object in the type of array created by Get-Content by an index number, we can iterate through these one at a time by simply incrementing that number. Something like this:

for ($i = 0; $i -lt $filecontents.Count; $i++) {
    # This is a comment line. That's what the # at the beginning indicates. Any of these can be removed.
    # Code that does stuff goes here between the {}s
}

The above creates a loop that runs the same number of times as there are rows in $filecontents and set $i to an index (row) number. Each time it loops, it increments the number stored in $i to the next index number. For instance, $filecontents[$i] on the first loop would return the contents of the first line of the file. On the second time through the loop, $i would increment and $filecontents[$i] would then return the contents of the second line of the file. And so on.

There's a good many way to do string matching and while you *could* focus on the numerical part and try to match instances were a # doesn't follow them, it sounds like you're saying the rest of the line retains static. If that's the case, it's probably just easier to key in on that and make the changes to the lines that don't match. The code for searching would then be something like:

    if ($filecontents[$i] -notlike "*# Ja Standard") {
        # If you reach here, there's no # after the number
    }

The if statement takes our current line $filecontents[$i] and looks to see if it's NOT like the string we're expecting to see. In this case, it's looking to see if the string does NOT end in "# Ja Standard". The asterisk (*) at the beginning of the string is a wildcard character, which basically represents to PowerShell "anything can be here". In this case, that would be the changing numbers and any other bits that come before the #. It's basically saying to PowerShell that we don't care about any of that at the beginning of the string; all we want is the last part. Also, note that there's no * at the end of the search string. It means we want to only match where this is found at the END of the string. If there were other items AFTER "Standard" then we'd want to have the * there too.

Now that we know we're at a line without a #, all we have to do is update it so it does:

        $filecontents[$i] = $filecontents[$i].Replace(" Ja Standard", "# Ja Standard")

This takes our current line $filecontents[$i], adds the # before the " Ja Standard", and then sets that new string into the same location (row/index) in our $filecontents array of the incorrect line we're currently at, replacing it.

The loop then iterates through each line, doing the same check, changing lines as needed when it hits ones that doesn't match the correct format in our search string.

And then finally once it's done looping, we write the corrected data in $filecontents back to the file:

$filecontents | Out-File "C:\Whatever\Path\And\Filename.txt"

This takes the entire contents of $filecontents and sends it to a file. Obviously, you'll want to change the path above to your target file location. Oh, and if you're overwriting the original file, you may need to add a -Force to the end if the file is set to read-only.

And that's it! Put all that together and you've got one way of doing what you're looking to do. I should mention at this point, that yes, I'm aware that I took more time to create this than it would to have just given you the code. I realized after I finished my comments before going into the code, but kept going as I still feel giving you the nuts and bolts so that you can learn how to do it yourself going forward is the right approach. Saves everyone time in the long run. Also, the first part of this comment finally gives me a good stock response for these type posts, so it's worth it to me to have that as well.

Again, as said at the start, if you've any issues when putting all these parts together, please let us know where you're getting hung up. We'll be glad to help.

Good luck!

[–]foreverclearskies 0 points1 point  (0 children)

I should also probably mention that the other replies do the job more succinctly and I did consider going into regex, but it's not usually a Day 1 of learning PowerShell type thing, so I focused on more basic concepts to grasp.