I tried changing the start and end date in the content of the file using the PowerShell script but it changes both dates to the same.
$path = "H:\oim\adcbsm007\adcbsm007.txt"
$path = "H:\oim\alps027\alps027.txt"
$word = "2016,01,28"
$replacement = "2016,01,29"
$text = get-content $path
$newText = $text -replace $word,$replacement
$newText > $path
$path = "H:\oim\adcbm007\adcsm007.txt"
$path = "H:\oim\alps027\alps027.txt"
$word = "2016,01,29"
$replacement = "2016,01,30"
$text = get-content $path
$newText = $text -replace $word,$replacement
$newText > $path
The content of the text file is something like this:
http://www.google.com="Global History"&customer=guest&password=guest&STARTTIME=2016,01,30,00,00,00&STOPTIME=2016,01,30,00,00,00&POINTSEVERY=15 min&GRAPHTYPE=excel
You need to replace the end date before the start date, otherwise the start date will be the same as the end date after the first replacement. Therefore the second replacement will change both start and end date to the new end date value. Also, if you want to do the replacement in several files you can't put the paths in the same variable, lest the second path replaces the first one. Use a list and a foreach loop (or something similar) instead.
$paths = 'H:\oim\adcbsm007\adcbsm007.txt', 'H:\oim\alps027\alps027.txt'
$startOld = '2016,01,28'
$startNew = '2016,01,29'
$endOld = '2016,01,29' # == $startNew
$endNew = '2016,01,30'
foreach ($p in $paths) {
(Get-Content $p) -replace $endOld, $endNew -replace $startOld, $startNew |
Set-Content $p
}
Related
Problem is solved, but I don't understand why :-)
I have a Powershell script that perform replacements inside files (language metadata):
loads a list of replacement from a txt file into an array
gets all xml files from a Start folder
performs all the replacements from the array
performs a replacement on the filename based on the array first entry
saves the resulting files in a End folder
I've been using successfully variations of the exact same script for many years, with the only thing changing being the replacement file name and content... except today when creating another variant. The only change was the content of the substitution file, and suddenly the replacement did not happen anymore in the filename.
Here is the code:
#load the replacements from file
$data = Import-Csv -Path substitutions.txt -Header "Source", "Target", "Safe", "Count" -Delimiter "|"
#load the files to be processed
$xmlfiles = -join ($Startfolder, "*.xml")
$Fileset = Get-ChildItem $xmlfiles -recurse
foreach ($File in $Fileset) {
$NewFileName = ""
$WipFile = Get-Content $File
# set safe replacement flag to nothing
$flag = ""
#perform replacements
foreach ($item in $data) {
if ($WipFile -cmatch $item.Source) {
if ($item.Safe -eq 'yes') {
$WipFile = $WipFile -creplace $item.Source, $item.Target
$item.Count = $item.Count + 1
}
else {
$WipFile = $WipFile -creplace $item.Source, $item.Target
$item.Count = $item.Count + 1
$flag = "TOCHECK "
}
}
}
#replace language code in filename, based on first entry in the substitution list
$NewFileName = -join ($Endfolder, $flag, $file.name -creplace $data.Source[0], $data.Target[0])
Write-Host $NewFileName
#save file with updated content
$WipFile | Set-Content -Encoding Unicode ($File)
#move file to End folder
Move-Item $File $NewFileName
}
The substitution file is formatted as follows:
nl-NL|nl-BE|yes
After testing more, I discovered my new variant was failing if my substitution file had only one line. Add another one, and it works. How come?
I'm writing a script that takes the name of a printer from a csv file and for each printer it is supposed to modify a xml printer preference, change the name of the printer, generate a new guid and output the new xml file. It almost works. Problem is that the script also changes the clsid, because it has the same regex as the uid. Only the uid is supposed to change, in other words: only the second occurrence of the matching regex.
Heres what the xml file looks like:
<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="cop-fibu-eink" status="cop-fibu-eink" image="1" changed="2021-02-18 14:52:29" uid="{7D783062-5840-4CBD-BE9A-6334FD87A8D6}" removePolicy="1" userContext="1" bypassErrors="1"><Properties action="R" comment="" path="\\srv-print01\cop-fibu-eink" location="" default="1" skipLocal="0" deleteAll="0" persistent="0" deleteMaps="0" port=""/><Filters><FilterGroup bool="AND" not="0" name="EKBDOM1\cop-fibu-eink" sid="S-1-5-21-356607561-1380008178-1848903544-16152" userContext="0" primaryGroup="0" localGroup="0"/></Filters></SharedPrinter>
And this is the Powershell script:
Import-Csv .\printer_groups.csv | ForEach-Object {
$uid = ([guid]::NewGuid()).guid
((Get-Content -path C:\pc_inst\druckerliste\cop-it.xml -Raw) -replace "cop-fibu-eink", $($_.name)` -replace "\{[0-9a-z\-]*\}", $uid ) | Set-Content -Path .\xmls\$($_.name).xml
}
I can't figure it out. Hope you guys can help me. (:
My colleague figured it out. In case anyone is wondering:
Import-Csv C:\pc_inst\druckerliste\printer_groups.csv | ForEach-Object {
$uid = ([guid]::NewGuid()).guid
((Get-Content -path C:\pc_inst\druckerliste\cop-it.xml -Raw) -replace "cop-fibu-eink", $($_.name)` -replace 'uid="\{[0-9a-z\-]*\}"', ('uid="{' + $uid + '}"') ) | Set-Content -Path C:\pc_inst\druckerliste\drucker_xml_standard\$($_.name).xml
}
If your file content is xml, why not treat it as xml as opposed to plain text?
$oldText = #"
<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="cop-fibu-eink" status="cop-fibu-eink" image="1" changed="2021-02-18 14:52:29" uid="{7D783062-5840-4CBD-BE9A-6334FD87A8D6}" removePolicy="1" userContext="1" bypassErrors="1">
<Properties action="R" comment="" path="\\srv-print01\cop-fibu-eink" location="" default="1" skipLocal="0" deleteAll="0" persistent="0" deleteMaps="0" port="" />
<Filters>
<FilterGroup bool="AND" not="0" name="EKBDOM1\cop-fibu-eink" sid="S-1-5-21-356607561-1380008178-1848903544-16152" userContext="0" primaryGroup="0" localGroup="0" />
</Filters>
</SharedPrinter>
"#
$xml = [xml] $oldText;
and then you can change attribute values easily like this:
$xml.SharedPrinter.uid = "{" + [Guid]::NewGuid().ToString().ToUpperInvariant() + "};
and serialize it back to xml:
$newText = $xml.OuterXml;
write-host $newText;
Note - it might not matter, but your original uid attribute has enclosing braces and upper case letters (uid="{7D783062-5840-4CBD-BE9A-6334FD87A8D6}") so I've matched that in the new value...
I used something like this. It's not well-structured but it Just Works(tm). It does all off the GPP stuff instead of your problem, but you can get the overall idea.
# Configuration variables
$PrintServer = ""
$CSVFilePath = "printers.csv"
$XMLFilePath = "printers.xml"
# The code
Import-Module ActiveDirectory
$Domain = (Get-ADDomain).name
$ScriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$Now = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
# Set The Formatting
$XMLSettings = New-Object System.Xml.XmlWriterSettings
$XMLSettings.Indent = $true
$XMLSettings.IndentChars = " "
# Set the File Name Create The Document
$XMLWriter = [System.XML.XmlWriter]::Create($XMLfilePath, $XMLSettings)
# Write the XML Declaration
$XMLWriter.WriteStartDocument()
# Start the Root Element
$XMLWriter.WriteComment('Root of the policy')
$XMLWriter.WriteStartElement('Printers') # Start root
$XMLWriter.WriteAttributeString('clsid', '{1F577D12-3D1B-471e-A1B7-060317597B9C}')
Import-Csv (Join-Path -Path $ScriptPath -ChildPath $CSVFilePath) | ForEach-Object {
$GroupName = $_.Group
[Microsoft.ActiveDirectory.Management.ADGroup]$Group = Get-ADGroup -Filter { name -like $_.GroupName }
# Start SharedPrinter Element
$XMLWriter.WriteStartElement('SharedPrinter') # Start SharedPrinter
$XMLWriter.WriteAttributeString('clsid', '{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}')
$XMLWriter.WriteAttributeString('name', $_.Printer)
$XMLWriter.WriteAttributeString('status', $_.Printer)
$XMLWriter.WriteAttributeString('image', '1')
$XMLWriter.WriteAttributeString('bypassErrors', '1')
$XMLWriter.WriteAttributeString('changed', $Now)
$XMLWriter.WriteAttributeString('uid', [System.Guid]::NewGuid().ToString())
# Start Properties Element
$XMLWriter.WriteStartElement('Properties') # Start Properties
$XMLWriter.WriteAttributeString('action', 'R')
$XMLWriter.WriteAttributeString('comment', '')
$XMLWriter.WriteAttributeString('path', "\\$PrintServer\$($_.Printer)")
$XMLWriter.WriteAttributeString('location', '')
$XMLWriter.WriteAttributeString('default', $_.Default)
$XMLWriter.WriteAttributeString('skipLocal', '0')
$XMLWriter.WriteAttributeString('deleteAll', '0')
$XMLWriter.WriteAttributeString('persistent', '0')
$XMLWriter.WriteAttributeString('deleteMaps', '0')
$XMLWriter.WriteAttributeString('port', '')
$XMLWriter.WriteEndElement() # End Properties
# Start Filters Element
$XMLWriter.WriteStartElement('Filters') # Start Filters
# Start FilterGroup Element
$XMLWriter.WriteStartElement('FilterGroup')
$XMLWriter.WriteAttributeString('bool', 'AND')
$XMLWriter.WriteAttributeString('not', '0')
$XMLWriter.WriteAttributeString('name', "$Domain\$($Group.Name)")
$XMLWriter.WriteAttributeString('sid', $Group.SID)
$XMLWriter.WriteAttributeString('userContext', '1')
$XMLWriter.WriteAttributeString('primaryGroup', '0')
$XMLWriter.WriteAttributeString('localGroup', '0')
$XMLWriter.WriteEndElement() # End FilterGroup
$XMLWriter.WriteEndElement() # End Filters
$XMLWriter.WriteEndElement() # End SharedPrinter
}
$XMLWriter.WriteEndElement() # End root
# End, Finalize and close the XML Document
$XMLWriter.WriteEndDocument()
$XMLWriter.Flush()
$XMLWriter.Close()
I'm working on a script which will add some additional informations to a txt file. These informations are stored in a CSV file which looks like this (the data will differs each time the script will launch):
Number;A;B;ValueOfB
FP01340/05/20;0;1;GTU_01,GTU_03
FP01342/05/20;1;0;GTU01
The txt file looks like this (data inside will of course differ each time):
1|1|FP01340/05/20|2020-05-02|2020-05-02|2020-05-02|166,91|203,23|36,32|nothing interesting 18|33333|63-111 somewhere|||||
2|zwol|9,00|9,00|0,00
2|23|157,91|194,23|36,32
1|1|FP01341/05/20|2020-05-02|2020-05-02|2020-05-02|12,19|14,99|2,80|Some info |2222222|blabla|11-111 something||||
2|23|12,19|14,99|2,80
1|1|FP01342/05/20|2020-05-02|2020-05-02|2020-05-02|525,36|589,64|64,28|bla|222222|blba 36||62030|something||
2|5|213,93|224,63|10,70
2|8|120,34|129,97|9,63
2|23|191,09|235,04|43,95
What I need to do is to find a line which contains 'Number' and then add value 'A' and 'B' from a CSV in a form: |0|1 and then on the first line below, at the end, add 'ValueofB' in a form |AAA_01,AAA_03
So the first two lines should look like this at the end:
1|1|FP01340/05/20|2020-05-02|2020-05-02|2020-05-02|166,91|203,23|36,32|nothing interesting 18|33333|63-111 somewhere||||||0|1
2|zwol|9,00|9,00|0,00|AAA_01,AAA_03
2|23|157,91|194,23|36,32
Rest of lines should not be touched.
I made a script which uses select-string method with context to find what I need to - put that into an object and then add to previously found strings what I need to and put that in to an another object.
My script is as follws:
$csvFile = Import-Csv -Path Somepath\file.csv -Delimiter ";"
$file = "Somepath2\SomeName.txt"
$LinesToChange = #()
$script:LinesToChange = $LinesToChange
$LinesOriginal = #()
$script:LinesOriginal = $LinesOriginal
foreach ($line in $csvFile) {
Select-String -Path $file -Pattern "$($Line.number)" -Encoding default -Context 0, 1 | ForEach-Object {
$1 = $_.Line
$2 = $_.Context.PostContext
}
$ListOrg = [pscustomobject]#{
Line_org = $1
Line_GTU_org = $2
}
$LinesOriginal = $LinesOriginal + $ListOrg
$lineNew = $ListOrg.Line_org | foreach { $_ + "|$($line.A)|$($line.B)" }
$GTUNew = $ListOrg.Line_GTU_org | foreach { $_ + "|$($line.ValueofB)" }
$ListNew = [pscustomobject]#{
Line_new = $lineNew
Line_GTU_new = $GTUNew
Line_org = $ListOrg.Line_org
Line_GTU_org = $ListOrg.Line_GTU_org
}
$LinesToChange = $LinesToChange + $ListNew
}
The output is an object $LinesToChange which have original lines and lines after the change. The issue is I have no idea how to use that to change the txt file. I tried few methods and ended up with file which contains updated lines but all others are doubbled (I tried foreach) or PS is using whole RAM and couldn't finish the job :)
My latest idea is to use something like that:
(Get-Content -Path $file) | ForEach-Object {
$line = $_
$LinesToChange.GetEnumerator() | ForEach-Object {
if ($line -match "$($LinesToChange.Line_org)") {
$line = $line -replace "$($LinesToChange.Line_org)", "$($LinesToChange.Line_new)"
}
if ($line -match "$($LinesToChange.Line_GTU_org)") {
$line = $line -replace "$($LinesToChange.Line_GTU_org)", "$($LinesToChange.Line_GTU_new)"
}
}
} | Set-Content -Path Somehere\newfile.txt
It seemed promising at first, but the variable $line contains all lines and as such it can't find the match.
Also I need to be sure that the second line will be directly below the first one (it is unlikely but it can be a case that there will be two or more lines with the same data while the "number" from CSV file is unique) so preferably while changing the txt file it would be needed to find a match for a two-liner; in short:
find this two lines:
1|1|FP01340/05/20|2020-05-02|2020-05-02|2020-05-02|166,91|203,23|36,32|nothing interesting 18|33333|63-111 somewhere|||||
2|zwol|9,00|9,00|0,00
change them to:
1|1|FP01340/05/20|2020-05-02|2020-05-02|2020-05-02|166,91|203,23|36,32|nothing interesting 18|33333|63-111 somewhere||||||0|1
2|zwol|9,00|9,00|0,00|AAA_01,AAA_03
Do that for all lines in a $LinesToChange
Any help will be much appreciated!
Greetings!
Some strange text file you have there, but anyway, this should do it:
# read in the text file as string array
$txt = Get-Content -Path '<PathToTheTextFile>'
$csv = Import-Csv -Path '<PathToTheCSVFile>' -Delimiter ';'
# loop through the items (rows) in the CSV and find matching lines in the text array
foreach ($item in $csv) {
$match = $txt | Select-String -Pattern ('|{0}|' -f $item.Number) -SimpleMatch
if ($match) {
# update the matching text line (array indices count from 0, so we do -1)
$txt[$match.LineNumber -1] += ('|{0}|{1}' -f $item.A, $item.B)
# update the line following
$txt[$match.LineNumber] += ('|{0}' -f $item.ValueOfB)
}
}
# show updated text on screen
$txt
# save updated text to file
$txt | Set-Content -Path 'Somehere\newfile.txt'
I need to remove the time stamp details from each line which is present at the start. How can I achieve?
I tried to use
regex = "[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,4} [0-9]{1,2}:[0-9]{1,2}:[0-9]
{1,2}):[0-9]{1,3}"
and my approach was like
$Check = (Get-Content -Path .\file.txt|Select-Object -last 3|Out-String)
$Check = $Check -replace('$regex','')
The lines in text file.txt would be like :
[06/13/19 08:52:58] The new world
[06/13/19 08:52:58] Computing
[06/13/19 08:52:58] Technology
and alternate method would be to use the -split string operator and split on ] [that is close-bracket & space]. something like this ...
('[06/13/19 08:52:58] The new world' -split '] ')[1].Trim()
output = The new world
if it is a static stamp just use substring.
$start = Get-Content -Path C:\Windows\Panther\setupact.log -First 1
$start.Substring(11,8)
This for example only extracs the timestamp.
in your case:
$start = "[06/13/19 08:52:58] Technology"
$start.Substring(20)
this removes it.
Hope it helps! BR
Edit (see comment):
$content = Get-Content .\Desktop\test.txt
$newLine = ""
foreach($line in $content){
if($line.IndexOf("[") -eq 0){
$newLine += $line.Substring(20) + " "
$prev = $true
}
else{
if($line -ne ""){
Write-Host $newLine
$newLine = ""
}
write-host $line
$prev = $false
}
}
$xml = [xml](Get-Content C:\temp\STA\*.dtsConfig)
$xml.SelectNodes('//ConfiguredValue')|%{$_.'#text'=($_.'#text' -replace '_\d+',[datetime]::Today.ToString('_MMddyyy'))}
$xml.SelectNodes('//ConfiguredValue')|%{$_.'#text'}
xml.Save('C:\temp\STA\*.dtsConfig')
from first 3 steps I want to check tag in ConfiguredValue in dtsConfig named PackageDependencies_somedate(20110528) and I want to change PackageDependencies_currentdate(20130619),
there is change some date to current date and save a file,
http://i.stack.imgur.com/EHH6h.jpg
Your code should be like following:
ls C:\temp\STA\*.dtsConfig | foreach {
$file = $_.FullName;
$xml = [xml](Get-Content $file)
$todayStr = [datetime]::Today.ToString('_MMddyyy')
#($xml.SelectNodes('//ConfiguredValue')) | %{
$_.'#text'=($_.'#text' -replace '_\d+',$todayStr)
}
$xml.Save($file)
}