modified date assistance - powershell

I have this piece of code that changes a string if it exist. It works perfectly. However, even if the Server1 string doesn't exist in the file it changes the modified date of the file. What I need it to do is if the string Server1 doesn't exist ignore and move on to the remaining files in the folder.
Does anyone here know how I can go about achieving this?
$filenames = Get-ChildItem "C:\test\*.dtsconfig" -Recurse |
select -Expand FullName
foreach ($filename in $filenames) {
(Get-Content $filename) -replace 'Server1', 'Server2' | Set-Content $filename
}

Write the file only if it actually contains the string "Server1":
$txt = Get-Content $filename
if ($txt -like '*Server1*') {
$txt -replace 'Server1', 'Server2' | Set-Content $filename
}

$fileNames = Get-ChildItem "C:\test\*.dtsconfig" -Recurse | Select -Expand FullName
foreach ($filename in $filenames) {
$file = Get-Content $fileName
If ($file -like "*Server1*") {
Get-Content $fileName -replace 'Server1', 'Server2' | Set-Content $fileName
}
}
I've added in an if statement so it checks before making any changes.

Related

Write a script to sort words in alphabet order from specific file and put them into 26 text files named A.txt, B.txt, and so on up to Z.txt

I need to sort words alphabetically from a specific file and put them into 26 text files named A.txt, B.txt and so on up to Z.txt.
$Content = Get-Content ".\\1.txt"
$Content = ($Content.Split(" .,:;?!/()\[\]{}-\`\`\`"")|sort)
$linecount = 0
$filenumber = 0
$destPath = "C:\\test"
$destFileSize = 26
$Content |Group {$_.Substring(0,1).ToUpper()} |ForEach-Object {
$path = Join-Path $destPath $_.Name
$\_.Group |Set-Content $path
}
$Content | % {
Add-Content $destPath$filenumber.txt "$\_"
$linecount++
If ($linecount -eq $destFileSize) {
$filenumber++
$linecount = 0
}
}
You could do something like this, but this also could mean some files may not be written if there are no words beginning with a certain letter found in the file:
$destPath = "D:\test"
(Get-Content -Path 'D:\Test\Lorem.txt' -Raw) -split '\W' -ne '' |
Group-Object {$_.Substring(0,1).ToUpperInvariant()} |
Where-Object {$_.Name -cmatch '[A-Z]'} | ForEach-Object {
$_.Group | Sort-Object | Set-Content -Path (Join-Path -Path $destPath -ChildPath ('{0}.txt' -f $_.Name))
}
If you always want exactly 26 files even if some may contain nothing, use this instead
$destPath = "D:\test"
$wordGroups = (Get-Content -Path 'D:\Test\Lorem.txt' -Raw) -split '\W' -ne '' |
Group-Object {$_.Substring(0,1).ToUpperInvariant()}
foreach ($char in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' -split '(.)' -ne '')) {
$outFile = Join-Path -Path $destPath -ChildPath ('{0}.txt' -f $char)
$group = $wordGroups | Where-Object { $_.Name -eq $char }
if ($group) { $group.Group | Sort-Object | Set-Content -Path $outFile } # output the found words
else { $null | Set-Content -Path $outFile } # or create an empty file
}
The Where-Object {$_.Name -cmatch '[A-Z]'} clause makes it ignore words starting with some other character than A to Z

Replace the text for all files in a Directory

I have written the below conditional script to go through the files in the directory and replace the one text in all files only if file contains the word as 'Health'
cd -Path "\\shlhfilprd08\Direct Credits\Temp2"
ForEach ($file in (Get-ChildItem -Path "\\shlhfilprd08\Direct Credits\Temp2"))
{
$filecontent = Get-Content -path $file -First 1
if($filecontent -like '*Health*'){$filecontent = $filecontent -replace 'TEACHERF','UniHlth '}
Set-Content $file.PSpath -Value $filecontent
}
I come across with two issues such as
If the ($filecontent -like 'Health'), it is replacing the word in first raw and deleting other rows along with replace.I do not want that to happen
I'm getting set-content to path is denied error message for file content does not contain the Health text
Can you try with this
cd -Path "\\shlhfilprd08\Direct Credits\Temp2"
$configFiles = Get-ChildItem . *.config -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "TEACHERF", "UniHlth " } |
Set-Content $file.PSPath
}
I would try this; it worked for me in a little file
(make a small copy of a few data into a new folder and test it there)
$path = "\\shlhfilprd08\Direct Credits\Temp2"
$replace ="TEACHERF" #word to be replaced
$by = "UniHlth " #by this word (change $replace by $by)
gci $path -file | %{
foreach($line in $(Get-content $_.Fullname)){
if($line -like $replace){
$newline = $line.Replace($($replace),$($by))
Set-Content $_.FullName $newline
}
}
}

Filter lines according to word by powershell

I want to filter lines according to specific word from file in powershell.
For example: the files animal1.txt and animal2.txt. Every file contain lines
dog
cat
dog
dog
bird
Then I want to create two derived files:
animal1_bak.txt that stores lines which contains the word 'dog' from animal1.txt
animal2_bak.txt that stores lines which contains the word 'dog' from animal2.txt
What I found on web is:
Select-String -Path "*.*" -Pattern "dog"
But the instruction to create the derived word is missing.
What can I do?
You can first get-content and use set-content like below
Get-Content -Path E:\KTDocs\Scripts\animal1.txt | where {
$_ -like '*dog*'} |Set-Content e:\animalbak.txt
try Something like this
select-string -Path "c:\temp\animal*.txt" -Pattern "dog" | Group Path | %{
$FileName="{0}_bak.txt" -f $_.Name
$_.Group.Line | select -unique | Out-File $FileName -Append
}
$folderpath = "D:\AnimalFolder" # your folder path here
$Allfiles = Get-ChildItem -Path $folderpath -Recurse -File -Force -ErrorAction SilentlyContinue |where{$_.Name -match ".txt"} |Select-Object -expandproperty FullName
foreach($filepath in $allfiles)
{
$Data = get-content $filepath
foreach($line in $data)
{
if($line -match "dog")
{
$newpath = $filepath.split('.')[0]
$getfullpath = $newpath + "_bak.txt"
$line | out-file $getfullpath -append
}
}
}

Get-ChildItem Zero Results Output

I have an issue that I cannot resolve no matter which way I am wrapping it up. I am including my latest code which is not giving me the desired outcome and the code for a solution that does work but for only one file at a time. I cannot work out how to loop through each of the files automatically however.
In a nutshell, I have a directory with many CSV files some of the entries within the CSVfile have a negative value (-) I need to remove this minus sign in all instances.
Now what works is if I use the following (on a single file)
$content = Get-Content "L:\Controls\BCR\0001cash.csv" | ForEach {$_ -replace $variable, ""} | Set-Content "L:\controls\bcr\0001temp.csv"
What I am trying to do is iterate through the many thousand of these objects automatically and not have to refer to them individually.
I started with:
$Directory = "L:\Controls\BCR\"
$variable = "-"
$suffix = ".tmp"
To define the directory, minus symbol that I want to remove and the suffix of the file I want to change to...
$Files = Get-ChildItem $Directory | Where-Object {$_.Extension -like "*csv*"} | Where-Object {$_.Name -like "*cash*"}
Is obtaining each of the files that I wish to work with
And I am then working with
ForEach ($File in $Files) { Get-Content $Files | ForEach {$_ -replace $variable, ""} | Set-Content {$_.Basename + $Variable}
The results however are nothing...
At a loss? Anyone???
$Directory = "L:\Controls\BCR\"
$variable = "-"
$suffix = ".tmp"
$Files = Get-ChildItem $Directory | Where-Object {$_.Extension -like "*csv*"} | Where-Object {$_.Name -like "*cash*"}
$process = ForEach ($File in $Files) { Get-Content $Files | ForEach {$_ -replace $variable, ""} | Set-Content {$_.BaseName + $suffix}
}
You are using the wrong variable in the Get-Content cmdlet ($Files instead of $File). Also You can simplify your script:
$Directory = "L:\Controls\BCR\"
$variable = "-"
$suffix = ".tmp"
Get-ChildItem $Directory -Filter '*cash*csv' |
ForEach-Object {
(Get-Content $_ -Raw) -replace $variable |
Set-Content {$_.BaseName + $suffix}
}

Replace string content between quotes in file

I have made this loop to iterate some files that I want to replace content in.
The content that I want to replace is a string which can look something like this: foo="1".
What I need your help with is how to find the string (regexp I guess) and update the file with a new value, like 2 for example.
$files = Get-ChildItem -Recurse -Filter "*.config"
foreach ($file in $files)
{
Get-Content $file.FullName
}
Read-Host
From the sample code in the question, I assume you're attempting to update a .NET configuration file (ie. a web.config or app.config file).
Given that these files are really XML files, you may want to treat them as such:
$files = Get-ChildItem -Recurse -Filter "*.config"
foreach ($file in $files)
{
# Create an XmlDocument object from the file
$configXml = [xml](Get-Content $file.FullName)
# Find all the nodes in the document
$xmlNodes = $configXml.SelectNodes('//*')
# Keep track of whether we make changes or not
$changeCount = 0
foreach($node in $xmlNodes)
{
# Check if node has a "foo" attribute
if($node.HasAttribute('foo'))
{
# Set 2 as the value
$node.SetAttribute('foo',2)
$changeCount++
}
}
if($changeCount)
{
# At least one node was updated, save to file
$configXml.Save($file.FullName)
}
}
You can try regex. Ex.
$files = Get-ChildItem -Recurse -Filter "*.config"
$find = 'foo=".*?"'
$replace = 'foo="4"'
foreach ($file in $files)
{
Get-Content $file.FullName |
Foreach-Object { $_ -replace $find, $replace } |
Set-Content $file.Fullname
}
}
Read-Host
Or to only modify files that match:
$files = Get-ChildItem -Recurse -Filter "*.config"
$find = 'foo=".*?"'
$replace = 'foo="4"'
foreach ($file in $files)
{
$content = Get-Content $file.FullName
if(Select-String -InputObject $content -Pattern $find -Quiet) {
$content |
Foreach-Object { $_ -replace $find, $replace } |
Set-Content $file.Fullname
}
}
Read-Host
This should answer your question
$files = Get-ChildItem -Recurse -Filter "*.config"
foreach ($file in $files)
{
$fileContent = Get-Content $file.FullName
$newContent = $fileContent -replace 'foo="1"', 'foo="2"'
Set-Content $file.FullName $newContent
}
Further reading here: Use PowerShell to Replace Text in Strings