Replacing word if condition is met - powershell

I want to replace the word "XRF " with "CALC" at column 27 to 30 in line 5 of file attached, if all values in column named "Total" are 99.95 like in the file attached.
$InFolder = "C:\sif\"
$OutFolder = "C:\Edited\"
$files = Get-ChildItem $InFolder -Recurse -Include *.sif
foreach ($file in $files) {
$OutFile = $OutFolder + $file.BaseName + "_FeC.sif"
$OutFile
$Lines = Get-Content $file
$Fe_C = "Y"
foreach ($Line in $Lines) {
while ($Fe_C -ne "N") {
if ($Line.ReadCount -ge 8) {
if (($line.Split(" ")) -eq "99.95") {
$Fe_C = "Y"
} else {
$Fe_C = "N"
}
}
}
}
}

You need to check if none of the data lines has a value other than 99.95 in data column 15, and if so replace the first occurrence of "XRF" in line 5 with "CALC".
To do that replace this:
$Lines = Get-Content $file
$Fe_C = "Y"
foreach ($Line in $Lines) {
...
}
with this:
$Lines = Get-Content $file
$different = [bool]($Lines |
Select-Object -Skip 7 |
Where-Object { $_ } |
Where-Object { ($_ -split '\s+')[15] -ne '99.95' })
if (-not $different) {
$Lines[4] = $Lines[4] -replace 'XRF (.*)', 'CALC$1'
}
Set-Content -Path $file -Value $Lines

Using regular expressions and assuming the Total column is the last:
if (($lines[7..($lines.count-1)] -notmatch '\s99\.95\s*$|^\s*$').count -eq 0) {
$lines[4] = ([regex]'XRF').replace($lines[4], 'CALC', 1)
}

Related

How to modify Firefox config (pref.js) line using Powershell

Modifying the Mozilla Firefox Pref.js file using PowerShell.
Need to modify the pref.js file line to reflect a new value
(Hence, instead of any value under user_pref("network.automatic-ntlm-auth.trusted-uris", "*"); to show user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com") or just add changes after the *
$TopDir = "$env:APPDATA\Mozilla\Firefox\Profiles"
$FileName = 'prefs.js'
$DefaultProfileDir = (Get-ChildItem -LiteralPath $TopDir -Directory).
Where({
$_.FullName -match '\.default'
}).FullName
$FullFileName = Join-Path -Path $DefaultProfileDir -ChildPath $FileName
$data = foreach($line in Get-Content $FullFileName)
{
if($line -contains 'user_pref("network.automatic-ntlm-auth.trusted-uris".*')
{
$line -replace '*' , 'user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com");'
}
else
{
$line
}
}
$data | Set-Content C:\testfolder\test2.txt
Nelson,
I didn't have your line in my FF profile but I got the code to work on another line so you should be able to modify it to work with yours.
$TopDir = "G:\Test"
$FileName = 'prefs.js'
$FullFileName = "$TopDir\$FileName"
Clear-Host
$Data = foreach($line in Get-Content $FullFileName) {
if( ($line.IndexOf('browser.bookmarks.restore_default_bookmarks')) -ne -1)
{
If ($line.IndexOf('false') -ne -1) {
$line = $line.replace( 'false' , 'true')
}
}
$line
}
$data | Set-Content $("$TopDir" + "\prefs2.js")
I think your code would be:
$TopDir = "$env:APPDATA\Mozilla\Firefox\Profiles"
$FileName = 'prefs.js'
$DefaultProfileDir = (Get-ChildItem -LiteralPath $TopDir -Directory).
Where({
$_.FullName -match '\.default'
}).FullName
$FullFileName = Join-Path -Path $DefaultProfileDir -ChildPath $FileName
$Data = foreach($line in Get-Content $FullFileName) {
if( ($line.IndexOf('network.automatic-ntlm-auth.trusted-uris')) -ne -1)
{
If ($line.IndexOf('*') -ne -1) {
$line = $line.replace( '*' , 'abc.com,.abcd.com,.abcde.com')
}
}
$line
}
$data | Set-Content C:\testfolder\test2.txt
Note: -contains is designed for lists.
HTH
I extended it to be easier to use any property
Input
user_pref("foo", "bar")
user_pref("network.automatic-ntlm-auth.trusted-uris", "*")
Output
user_pref("foo", "bar")
user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com")
$lines = 'user_pref("foo", "bar")', 'user_pref("network.automatic-ntlm-auth.trusted-uris", "*")'
# multi-line regex for readability
$regex = '(?x)
(?<prefix>user_pref\()
(?<name>
".*"
)
\s*,\s*
(?<value>
".*"
)
(?<suffix>.*)
'
"`ninput:"
$lines
"`noutput:"
$lines | ForEach-Object {
if($_ -match $regex) {
if($matches.name -eq '"network.automatic-ntlm-auth.trusted-uris"') {
$_ = '{0}{1}, {2}{3}' -f #(
$Matches.prefix,
$Matches.name,
'".abc.com,.abcd.com,.abcde.com"',
$Matches.suffix
)
}
}
$_
}

How to read a specific item of INI file using PowerShell?

I want to read a specific item of my INI file, I have 5 Items in the section of my INI file, and I want to read 4 items, except items number 3.
I already tried to read all the items, but I can not find a way how to specify the item that I want to read and the format of the file that I read is like this:
Name Value
AA 12
BB 13
CC 14
DD 15
EE 16
I used this command to execute it.
File1.ps1 Read-File -FilePath C:\Users\Data.ini -a_section Code -store C:\Users\
function Read-File {
Param(
[Parameter(Mandatory=$true)]$FilePath,
[Parameter(Mandatory=$true)]$a_section,
[Parameter(Mandatory=$true)]$store
)
$input_file = $FilePath
$ini_file = #{}
Get-Content $input_file | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
$Path_Store = $store
$Get_Reg = $ini_file.($a_section)
$Output = $Get_Reg | Out-File $Path_Store\Out_Test
}
$cmd, $params = $args
& $cmd #params
My expectation result, I have an output file like this
AA=12
BB=13
DD=15
EE=16
My INI File look like this:
[Name]
1=Joe
2=Grace
[Code]
AA=12
BB=13
CC=14
DD=15
EE=16
Try this:
function Get-IniSection {
Param(
[Parameter(Mandatory=$true)]$Path,
[Parameter(Mandatory=$true)]$SectionName
)
$ini_file = #{}
Get-Content $Path | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file += #{ $section = #{} }
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section] += #{ $key = $value }
}
}
return $ini_file[$SectionName]
}
$section = Get-IniSection -Path "C:\temp\test.ini" -SectionName "code"
$section.GetEnumerator() | Where-Object { $_.Name -ne "EE" }
$section.GetEnumerator() | ForEach-Object { "$($_.Name)=$($_.Value)" }
$section.GetEnumerator() |
Where-Object { $_.Name -in #("A1","AE","AP","AS","E1","E2","JP","M1","M2","N1","N2","P1","P2","P3","P4","PR","RU","S1","S2","W1","W2","W3","W4","ZH") } |
Select-Object -ExpandProperty "Value"
$section.GetEnumerator() |
Where-Object { $_.Name -in #("A1","AE","AP","AS","E1","E2","JP","M1","M2","N1","N2","P1","P2","P3","P4","PR","RU","S1","S2","W1","W2","W3","W4","ZH") } |
Foreach-Object { ($_.Value -split ",")[0] }

Removing extra blank space from PowerShell output

I have a PowerShell program to replace some strings with another from an input file but the output file has an extra space/line when compared to input file.
$InputACKFile = 'C:\Testing_Newline\Aj*.dat'
Write-Host "Found " ($InputACKFile | Measure-Object).Count " files to process"
$InputACKFile = Get-ChildItem $InputACKFile
foreach ($xfile in $InputACKFile) {
Write-Host "Processing file: $xFile`r"
#((Get-Content $xfile).Replace("~", "`n")) | Out-File $xfile.FullName
[System.IO.File]::ReadAllText($xfile).Replace("~","`n") |
Set-Content $xfile
$flag = 0
(Get-Content $xfile | ForEach {
if ($_ -match "^PQ\*") {
$_ -replace "test1", "test2"
} elseif ($_ -match "^TA\*") {
$_ -replace "test1", "test2"
} elseif ($_ -match "^ABC\*RS\*") {
$_ = '';
$flag = 1
} elseif ($_ -match "^(DE\*)([0-9]+)(\*[0-9]+)$" -and $flag -eq 1) {
$_ -replace ($matches[2]), ([int]::Parse($matches[2])-1);
$flag = 0
} else{
$_
}
}) | Out-File $xfile.FullName -Encoding Ascii
((Get-Content $xfile) -join("~")) | Set-Content $xfile.FullName
}

parsing script never ends

i have the following script but it does never end executing.
what could be the issue ? I tried to debug it but apparently it works correctly with a single file, but when I throw it against a folder full of content fails.
$path = split-path -parent $MyInvocation.MyCommand.Definition
$files = Get-ChildItem "$path\CodeForCertification\5_SourceCode\*" -Include *.c,*.h -Recurse | where{
! $_.PSIsContainer
}#$PSScriptRoot
ForEach ($file in $files){
$data = Get-Content -Path $file.FullName
$feature = Get-Content "$path\Disabled_Features.txt"
#[System.ArrayList]$Modifier
$nl=[Environment]::NewLine
$Modifier=#()
$flag=0
$data = $data | ForEach-Object -Begin {
$ignore = $false; $levels = 0
} -Process {
for($counter=0; $counter -lt $feature.Count; $counter++){
$parse = $feature[$counter]
if($_ -match "^#ifdef $parse" -And $flag -eq '0') {
$ignore = $true
$flag = 1;
}
}
if($ignore) {
if ($_ -match "^#ifdef") {
$levels++
}elseif ($_ -match "#endif") {
if($levels -ge 1) {
$levels--
if($levels -eq '0'){
$ignore = $false
}
}
}
}else {
$flag=0
$temp=$_
$_
$Modifier+="$temp"
}
}
$data | Out-File $file.FullName
}
OK, Jackson, let's solve your problem before you enter some kind of question spam filter ;-)
Consider this (just put it somewhere at the start of your script):
function RemoveUndesiredFeatures([string[]]$lines,[string[]]$undesiredFeatures)
{
$inIgnoreBlock = $false
$nestingLevel = 0
foreach ($line in $lines)
{
if ($inIgnoreBlock)
{
# Only search for nested blocks and end of block
if ($line -like "#ifdef*")
{
$nestingLevel++
}
elseif ($line -like "#endif*")
{
$nestingLevel--
}
if ($nestingLevel -eq 0)
{
$inIgnoreBlock = $false
}
}
else
{
# Search for undesired feature
$isIfdefMatch = $line -match "#ifdef (?<feature>\w+)"
if ($isIfdefMatch -and ($Matches.feature -in $undesiredFeatures))
{
# Ignore Feature
$inIgnoreBlock = $true
$nestingLevel++
}
else
{
# Output line
$line
}
}
}
}
Here is my example to use it:
$undesiredFeatures = #("F1","F2") # Just as example. Get-Content on a file with features is also fine
$files = Get-ChildItem *.c,*.h -Recurse # Again, just as example
foreach ($file in $files)
{
$lines = Get-Content $file.FullName
$changedLines = RemoveUndesiredFeatures $lines $undesiredFeatures
if ($changedLines.Count -ne $lines.Count)
{
# Features were removed. Write out changed file (to a different file to preserve my test files)
Set-Content -Value $changedLines -Path "$($file.FullName).changed"
}
}

Add Content in Powershell

I need to search through multiple files and underneath specific lines i need to insert lines referenced previously in each respective file. So far i cannot get my script to work at all.
This is what i have so far :
$TextLocation = "M:\test"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pagetitle = "DS_PGSEQ-DC:"
$a = Get-Content $file.FullName | Select-String "AssignedToUserID-TZ"
$b = Get-Content $file.FullName | Select-String "EFormID-TZ"
Foreach ($line in $file)
{
if([String]$line -eq "DS_PGSEQ-DC:0001")
{
}
elseif([String]$line -eq $pagetitle)
{
Add-Content $file.FullName ($a -and $b)
}
}
}
There are two common ways for inserting text into a text file:
Process the input file(s) line-by-line, write the output to a temporary file and replace the input file(s) with them temp file afterwards.
for ($file in $files) {
$filename = $file.FullName
Get-Content $filename | % {
if ( $_ -match 'seach pattern' ) {
$_
"new line"
}
} | Out-File $tempfile
MoveItem $tempfile $filename -Force
}
Read the entire content of the file(s), insert the text by using a regular expression replacement, and write the modified content back to the file(s).
for ($file in $files) {
$text = [System.IO.File]::ReadAllText($file.FullName)
$text -replace '.*search pattern.*', "`$0`nnew line" |
Out-File $file.FullName
}
$TextLocation = "M:\test"
$Outputlocation = "M:\test\output"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pattern = "\d\d\d[2-9]"
$found=$false
$contains=$false
$lines = Get-Content($file.FullName) |
Foreach-object {
if ($_ -match "AssignedToUserID-TZ") {
$a = $_
}
if ($_ -match "EFormID-TZ") {
$b = $_
}
if ($_ -match "DS_PGSEQ-DC:$pattern") {
if($found -eq $false) {
$found=$true
}
} else {
$found=$false
}
if ($found -eq $true) {
$contains=$true
#Add Lines after the selected pattern
$_
$a
$b
}
if ($found -ne $true) {
$_
}
} | Set-Content($Outputlocation + "\" + $file.Name)
}