replacing text in Powershell every alternate match - powershell

I have looked at this question, and it's close to what I need to do, but the text I need to replace is inconsistent.
I need to replace "`r`n with ", but only the first of the 2 adjacent lines
example: (the full file is 50k lines and up to 500 chars wide)
ID,Name,LinkedRecords
54429,Abe,
54247,Jonathan,"
63460|63461"
54249,Teresa,
54418,Cody,
58046,Joseph,
58243,David,
,Barry,"
74330"
C8876,Simon,
X_10934,David,
should become
ID,Name,LinkedRecords
54429,Abe,
54247,Jonathan,"63460|63461"
54249,Teresa,
54418,Cody,
58046,Joseph,
58243,David,
,Barry,"74330"
C8876,Simon,
X_10934,David,
I can see this will probably be useful, but I'm having a hard time getting the command to work as desired

If the `r`n characters are literal, then you can do the following:
[System.IO.File]::ReadAllText('c:\path\file.txt') -replace '(?<=,")`r`n\r?\n' |
Set-Content c:\path\file.txt
If `r`n are actual carriage return and line feed chars, then you can do the following:
[System.IO.File]::ReadAllText('c:\path\file.txt') -replace '(?<=,")\r\n' |
Set-Content c:\path\file.txt
Note if memory becomes an issue, a different approach may be needed.

Related

Powershell add text after 20 characters

I want to add text after exactly 20 characters inklusiv blanks. Does someone have a short solution with add-content or can post a link where i can read about a way to do so.
My file looks somthing like this:
/path1/path1/path1 /path2/path2/path2 /path3/path3/path3
than an application will read this pahts (not my application and i can not edit it in any way) the application will read these paths and it will read them on their position so if the second path starts 10 characters later it wont recognize it, so i can not simply replace the path or edit it easy sinc the path has not always the same lenght. Why the application reads it that way dont ask me.
So i need to add a string at start than the next string at exactly character 20 and than the next at charcter 40.
You could use the regex -replace operator to inject a new substring after 20 characters:
PS ~> $inject = "Hello Manuel! ..."
PS ~> $string = "Injected text goes: and then there's more"
PS ~> $string -replace '(?<=^.{20})',$inject
Injected text goes: Hello Manuel! ...and then there's more
The regex pattern (?<=^.{20}) describes a position in the string where exactly 20 characters occur between the start of the string and the current position, and the -replace operator then replaces the empty string at said position with the value in $inject
This did it for me
$data.PadRight(20," ") | Out-File -FilePath F:\test\path.txt -NoNewline -Append

Read from text file one character at a time

I'm trying to convert characters in a text file based one what type they are:
Letters > L
Numbers > #
Is there a way to iterate through a file on a per-character basis? The only way I can get it to work currently is nested loops iterating through individual lines within the file. If there's a simpler way, that cuts out a lot of code I'll have to wade through.
You can use Get-Content -Encoding Byte and convert from the byte value back to a character:
Get-Content foo.txt -Encoding Byte | foreach { [char]$_ }
You can use Get-Content -Raw and cast the result to [byte[]]. Not recommended for large files.
Both options above will give you all characters, including line breaks. Option 1 will not work with Unicode for obvious reasons; option 2 will.
Then there is the variant you mention already: Iterate twice, once by lines, once by character:
Get-Content foo.txt | foreach { [char[]] $_ | foreach { ... } }
If you don't need line breaks as characters I'd prefer this version since it should have reasonable runtime and memory requirements (e.g. it won't try to fit the whole file into memory).
get-content myfile.txt | foreach { $_.ToCharArray() }
This flattens the contents of your file into a long array of characters.
If you are processing very large files, the fastest (programmatic) method I have found is to use .NET StreamReader and StreamWriter. Utilizing these objects will allow you to read line-at-a-time into a string, perform manipulation, and then write to a new file line-at-a-time. At the end, delete your original and rename the new file accordingly.
If you don't need to programmatically solve this and can utilize regular expressions, I recommend UltraEdit. I don't know what wizardry they utilize, but it is MUCH faster at reading files than what I've managed to do in PowerShell.

Replace first two characters of each line of a file via PowerShell

I have a file that needs to have the first two characters of each line replaced. It seems easy but those same first two characters "|0" showup elsewhere in the file. So I've ended up having the replacement strings "$bp" all over the place. Any way to just replace the first instance of "|0" for each line only? Here is the sample data:
0|Corrupt Record|0|0|0|0|0|0|0|0|0
Your question is unclear (|0 vs 0|).
You can use this snippet to replace the 2 first characters of each line if they are 0|:
$oldContent = Get-Content "my/file"
$newContent = $OldContent | ForEach-Object { $_ -replace "^0\|","newstring" }
# simpler
#$newContent = $OldContent -replace "^0\|","newstring"
$newContent | Set-Content "my/file"
I'm sure there are other ways to do this, but here is how my approach would be.
To replace just the first occurrence of "0|" and have the remaining stay you can replace it like so.
$CorruptString = "0|Corrupt Record|0|0|0|0|0|0|0|0|0"
[regex]$ToReplace = "0\|"
$ToReplace.replace($CorruptString, "", 1)
This will Output:
Corrupt Record|0|0|0|0|0|0|0|0|0
Just a simple regex to replace the corrupt string and replace it with either nothing or whatever you wanted to replace it with. Naturally the 1 is so it only does it one time.
I believe that is what you were looking for. If not try to explain more.
EDIT: because there was some confusion with the post. To replace the first two characters in a string you can just do substring to remove the first two.
"0|Corrupt Record|0|0|0|0|0|0|0|0|0".Substring(2)

powershell - replace line in .txt file

I am using PowerShell and I need replace a line in a .txt file.
The .txt file always has different number at the end of the line.
For example:
...............................txt (first)....................................
appversion= 10.10.1
............................txt (a second time)................................
appversion= 10.10.2
...............................txt (third)...................................
appversion= 10.10.5
I need to replace appversion + number behind it (the number is always different). I have set the required value in variable.
How do I do this?
Part of this issue you are getting, which I see from your comments, is that you are trying to replace text in a file and saved it back to the same file while you are still reading it.
I will try to show a similar solution while addressing this. Again we are going to use -replaces functionality as an array operator.
$NewVersion = "Awesome"
$filecontent = Get-Content C:\temp\file.txt
$filecontent -replace '(^appversion=.*\.).*',"`$1$NewVersion" | Set-Content C:\temp\file.txt
This regex will match lines starting with "appversion=" and everything up until the last period. Since we are storing the text in memory we can write it back to the same file. Change $NewVersion to a number ... unless that is your versioning structure.
Not sure about what numbers you are keeping
About which part of the numbers, if any, you are trying to preserve. If you intend to change the whole number then you can just .*\. to a space. That way you ignore everything after the equal sign.
Yes, you can with regex.
Let call $myString and $verNumber the variables with text and version number
$myString = "appversion= 10.10.1";
$verNumber = 7;
You can use -replace operator to get the version part and replace only last subversion number this way
$mystring -replace 'appversion= (\d+).(\d+).(\d+)', "appversion= `$1.`$2.$verNumber";

Powershellv2 - remove last x characters from a string

I have a file containing a few thousand lines of text. I need to extract some data from it,
but the data I need is always 57 characters from the left, and 37 characters from the end.
The bit I need (in the middle) is of varying length.
e.g. 20141126_this_piece_of_text_needs_to_be_removed<b>this_needs_to_be_kept</b>this_also_needs_to_be_removed
So far I have got:
SELECT-STRING -path path_to_logfile.log -pattern "20141126.*<b>" |
FOREACH{$_.Line} |
FOREACH{
$_.substring(57)
}
This gets rid of the text at the start of the line, but I can't see how to get rid of the text from the end.
I tried:
$_.subString(0,-37)
$_.subString(-37)
but these didn't work
Is there a way to get rid of the last x characters?
to remove the last x chars in a text, use:
$text -replace ".{x}$"
ie
PS>$text= "this is a number 1234"
PS>$text -replace ".{5}$" #drop last 5 chars
this is a number
If I understand you correctly, you need this:
$_.substring(57,$_.length-57-37)
Though this doesn't seem to work precisely with the example you gave but it will give you the varying middle section i.e. starting at 57 chars from the start and ending 37 chars from the end
This is how to remove the last 37 characters from your string:
$_.subString(0,$_.length-37)
but arco´s answer is the preferred solution to your overall problem