I'm trying to get an application version from Version.txt file looping through a bunch of folders. It's not a big deal by itself but the problem is that there are a lot of other stuff in these files.
Examples:
'1.0.0.1'
'Version - 0.11.0.11'
'ApplicationName - 1.0.12.89'
'Definitely some useful information.
ApplicationName - 1.0.13.0'
The file always ends with the version but there are no other correlations. The length of the version is different every time because there can be different number of digits between dots.
It drives me crazy. Any suggestions?
solution 1
((get-content "C:\temp\file1.txt" -Tail 1) -split "-|'")[1].Trim()
#Code decomposed for explain
#get last row of file
$lastrowfile=get-content "C:\temp\file1.txt" -Tail 1
#split last row with - or ' as separator
$arraystr=$lastrowfile -split "-|'"
#take element 1 of split and trim final string
$arraystr[1].Trim()
Because the version is always at the last line, use the Get-Content cmdlet with the -tail parameter to read only the last line. Then select the version using the Select-String cmdlet and a regex:
(Get-Content 'Your_File_Path.txt' -Tail 1 | Select-String "(?<=- ).*(?=')").Matches.Value
Output:
1.0.13.0
Solution 2
((get-content "C:\temp\file1.txt" | where {$_ -like "*ApplicationName*"} | select -Last 1) -split "-|'")[1]
This would search the file for all lines that appear to have a version number on them, take the very last line with a match in that file, and return just the version number.
$content = Get-Content 'path\to\your\version.txt'
$regex = [regex]"\d+(\.\d+)+"
# Grab the last line in the version file that appears to have a version number
$versionLine = $content -match $regex | Select-Object -Last 1
if ($versionLine) {
# Parse and return the version
$regex.Match($versionLine).Value
}
else {
Write-Warning 'No version found.'
}
That works with all of the version numbers you posted, and would work if the version number appears to be at the end of the file, but there's additional whitespace afterward, etc.
you can use get-content and then split :
((get-content "C:\test.txt" | where {$_ -like "*ApplicationName*"} | select -Last 1) -split "-|'")[1]
Related
I need to loop through multiple text files and check for a $ value in position 7 on each line of text and replace it with an * when found. But ONLY when it is in position 7. I do not want to change it if it is found in other positions. This is as far as I have gotten. Any help would be greatly appreciated.
Get-ChildItem 'C:\*.txt' -Recurse |
foreach $line in Get-Content $_ {
$linePosition1to5 = $line.Substring(0,6)
$linePosition7 = $line.Substring(6,1)
$linePositionRest = $line.Substring(8)
if($linePosition7 = "$"){
$linePosition7 = "*"
}
$linePosition1to5 + $linePosition7 + $linePositionRest |
Set-Content $_
}
Is there something that doesn't work in your example, or just that all the nested substrings are annoying to work with?
I'd use regex for this one. e.g.
$Lines = Get-Content -Path "C:\examplefile.txt" -raw
$Lines -replace '(?m)(^.{6})\$', '$1*'
To explain the regex:
?m indicates that it's multiline, required because I used raw get-content rather than pulling an array. Array would work too, just needs a loop like you did.
^.{6} line start plus any 6 characters (capture group 1)
$ escaped dollar character
$1* Capture group 1 left as is, dollar replaced with *, anything else not captured and therefore left untouched.
Thanks for code and the explanation. I realized that I left out the -raw option and it did work. Putting it back in it seems to add a line to the end of each file. Unless you can think of reason why I shouldn't I was going to leave it out.
Get-ChildItem 'C:\TEST\*.txt' -Recurse | ForEach {
(Get-Content $_ | ForEach { $_ -replace '(?m)(^.{6})\$', '$1*'}) |
Set-Content $_
}
I want to write a script that would skip 1 line every time.
My text file looks like below :
Java 8 update
{243453-4544-34534-6565-7676772345}
Java 7 update
{23444-554-565767-435234-5426564647}
I want to write PowerShell script that should skip string.
Expected output:
{243453-4544-34534-6565-7676772345}
{23444-554-565767-435234-5426564647}
This is example text file but I have 200 lines of text file which is same format(1 line string and next line is product code).
Kindly help on this.
I got the answer using following script.
$codes= Get-Content %path to text file" | where {$_ -notmatch 'Java'}
Foreach($code in $codes)
{
write-host $code
}
You can try getting all the lines that don't contain 'java':
Get-Content .\data.txt |
Where-Object {$_ -notlike "*java*"}
This assumes the non-valid lines contain that word, but doesn't guarantee that the returned ones contain a correct value. It is probably better to do a positive match on the string you want, like this:
Get-Content .\data.txt |
Select-String -Pattern "{(\d+-){4}\d+}"
This will get the lines containing the number pattern, no matter how they are spaced (so, even if they are are the 1st, 9th, 12th and 28th lines).
Finally, if you really want every second line, regardless of content, try the modulus operator (%):
$i=1
Get-Content .\data.txt |
Where-Object {-not ($i++ % 2)}
the nice thing about this technique is you can get every 3rd line by replacing the '2' with '3', or every 4th line by replacing with a '4', etc.
I got the required output by using below code
$code= Get-Content %path of file% | Select-string '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$'
There are tons of ways. The not Java works if always Java.
You could introduce an if statement in your loop checking remainder of a variable.
$check=1
Foreach($line in (gc file.tx)){
If (($check % 2) -eq 0){
Do commands
}
$check = $check + 1
}
Also changing -eq 0 to 1 will return the opposite lines
I know that I can use:
gc c:\FileWithEmptyLines.txt | where {$_ -ne ""} > c:\FileWithNoEmptyLines.txt
to remove empty lines. But How I can remove them with '-replace' ?
I found a nice one liner here >> http://www.pixelchef.net/remove-empty-lines-file-powershell. Just tested it out with several blanks lines including newlines only as well as lines with just spaces, just tabs, and combinations.
(gc file.txt) | ? {$_.trim() -ne "" } | set-content file.txt
See the original for some notes about the code. Nice :)
This piece of code from Randy Skretka is working fine for me, but I had the problem, that I still had a newline at the end of the file.
(gc file.txt) | ? {$_.trim() -ne "" } | set-content file.txt
So I added finally this:
$content = [System.IO.File]::ReadAllText("file.txt")
$content = $content.Trim()
[System.IO.File]::WriteAllText("file.txt", $content)
You can use -match instead -eq if you also want to exclude files that only contain whitespace characters:
#(gc c:\FileWithEmptyLines.txt) -match '\S' | out-file c:\FileWithNoEmptyLines
Not specifically using -replace, but you get the same effect parsing the content using -notmatch and regex.
(get-content 'c:\FileWithEmptyLines.txt') -notmatch '^\s*$' > c:\FileWithNoEmptyLines.txt
To resolve this with RegEx, you need to use the multiline flag (?m):
((Get-Content file.txt -Raw) -replace "(?m)^\s*`r`n",'').trim() | Set-Content file.txt
If you actually want to filter blank lines from a file then you may try this:
(gc $source_file).Trim() | ? {$_.Length -gt 0}
You can't do replacing, you have to replace SOMETHING with SOMETHING, and you neither have both.
This will remove empty lines or lines with only whitespace characters (tabs/spaces).
[IO.File]::ReadAllText("FileWithEmptyLines.txt") -replace '\s+\r\n+', "`r`n" | Out-File "c:\FileWithNoEmptyLines.txt"
(Get-Content c:\FileWithEmptyLines.txt) |
Foreach { $_ -Replace "Old content", " New content" } |
Set-Content c:\FileWithEmptyLines.txt;
file
PS /home/edward/Desktop> Get-Content ./copy.txt
[Desktop Entry]
Name=calibre
Exec=~/Apps/calibre/calibre
Icon=~/Apps/calibre/resources/content-server/calibre.png
Type=Application*
Start by get the content from file and trim the white spaces if any found in each line of the text document. That becomes the object passed to the where-object to go through the array looking at each member of the array with string length greater then 0. That object is passed to replace the content of the file you started with. It would probably be better to make a new file...
Last thing to do is reads back the newly made file's content and see your awesomeness.
(Get-Content ./copy.txt).Trim() | Where-Object{$_.length -gt 0} | Set-Content ./copy.txt
Get-Content ./copy.txt
This removes trailing whitespace and blank lines from file.txt
PS C:\Users\> (gc file.txt) | Foreach {$_.TrimEnd()} | where {$_ -ne ""} | Set-Content file.txt
Get-Content returns immutable array of rows. You can covert this to mutable array and delete neccessary lines by index.Particular indexex you can get with match. After that you can write result to new file with Set-Content. With this approach you can avoid empty lines that powershell replace tool leaves when you try to replace smthing with "". Note that I dont guarantee perfect perfomance. Im not a professional powershell developer))
$fileLines = Get-Content $filePath
$neccessaryLine = Select-String -Path $filePath -Pattern 'something'
if (-Not $neccessaryLine) { exit }
$neccessaryLineIndex = $neccessaryLine.LineNumber - 1
$updatedFileContent = [System.Collections.ArrayList]::new($fileLines)
$updatedFileContent.RemoveAt($neccessaryLineIndex)
$updatedHostsFileContent.RemoveAt($domainInfoLineIndex - 1)
$updatedHostsFileContent | Set-Content $hostsFilePath
Set-Content -Path "File.txt" -Value (get-content -Path "File.txt" | Select-String -Pattern '^\s*$' -NotMatch)
This works for me, originally got the line from here and added Joel's suggested '^\s*$': Using PowerShell to remove lines from a text file if it contains a string
I have a text file that contains only one line with a version number of my application. An example would be 1.0.0.1. I would like to increment the build number. Using my example I would get the output 1.0.0.2 in the same text file.
How can I do it with PowerShell?
This might be over kill, but it shows the use of the type [version] which will save the need to do string manipulation.
$file = "C:\temp\File.txt"
$fileVersion = [version](Get-Content $file | Select -First 1)
$newVersion = "{0}.{1}.{2}.{3}" -f $fileVersion.Major, $fileVersion.Minor, $fileVersion.Build, ($fileVersion.Revision + 1)
$newVersion | Set-Content $file
The file contents after this would contain 1.0.0.2. The unfortunate part about using [version] is that the properties are read-only, so you can't edit the numbers in place. We use the format operator to rebuild the version while incrementing the Revision by one.
On the off chance there is some whitespace or other hidden lines in the file we ensure we get the first line only with Select -First 1.
One of several string manipulation based solution would be to split the contents into an array and then rebuild it after changes are made.
$file = "C:\temp\File.txt"
$fileVersion = (Get-Content $file | Select -First 1).Split(".")
$fileVersion[3] = [int]$fileVersion[3] + 1
$fileVersion -join "." | Set-Content $file
Split the line on its periods. Then the last element (third) contains the number you want to increase. It is a string so we need to cast it as an [int] so we get an arithmetic operation instead of a string concatenation. We then rejoin with -join.
$versionFile = Get-Content -Path "c:\temp\testing.txt"
$version = [version]($versionFile)
$newVersion = New-Object -TypeName System.Version -ArgumentList $version.Major, $version.Minor, $version.Build, ($version.Revision + 1)
$newVersion | Set-Content -Path "c:\temp\testing.txt"
One more string variation that removes the redundant assignment to the array member and includes a reminder on how to address the last element of an array. I think it is a little cleaner.
$file="C:\scripts\assemblyVersion.txt"
$versionparts = (get-content -Path $file).split('.')
([int]$versionparts[-1])++
$versionparts -join('.') | set-content $file
I have a situation that I need to remove some words from all text file in a folder.
I know how to do that only in 1 file, but I need to do it automatically for all text files in that folder. I got no idea at all how to do it in powershell.
The name of the files are random.
Please help.
This is the code
$txt = get-content c:\work\test\01.i
$txt[0] = $txt[0] -replace '-'
$txt[$txt.length - 1 ] = $txt[$txt.length - 1 ] -replace '-'
$txt | set-content c:\work\test\01.i
Basicly it jsut removes a "-" from first line and last line, but i need to do this on all files in the folder.
Get-ChildItem c:\yourfolder -Filter *.txt | Foreach-Object{
... your code goes here ...
... you can access the current file name via $_.FullName ...
}
Here is a full working example:
Get-ChildItem c:\yourdirectory -Filter *.txt | Foreach-Object{
(Get-Content $_.FullName) |
Foreach-Object {$_ -replace "what you want to replace", "what to replace it with"} |
Set-Content $_.FullName
}
Now for a quick explanation:
Get-ChildItem with a Filter: gets all items ending in .txt
1st ForEach-Object: will perform the commands within the curly brackets
Get-Content $_.FullName: grabs the name of the .txt file
2nd ForEach-Object: will perform the replacement of text within the file
Set-Content $_.FullName: replaces the original file with the new file containing the changes
Important Note: -replace is working with a regular expression so if your string of text has any special characters
something like this ?
ls c:\temp\*.txt | %{ $newcontent=(gc $_) -replace "test","toto" |sc $_ }
$files = get-item c:\temp\*.txt
foreach ($file in $files){(Get-Content $file) | ForEach-Object {$_ -replace 'ur word','new word'} | Out-File $file}
I hope this helps.
Use Get-Childitem to filter for the files you want to modify. Per response to previous question "Powershell, like Windows, uses the extension of the file to determine the filetype."
Also:
You will replace ALL "-" with "" on the first and last lines, using what your example shows, IF you use this instead:
$txt[0] = $txt[0] -replace '-', ''
$txt[$txt.length - 1 ] = $txt[$txt.length - 1 ] -replace '-', ''