Working Code:
Find Word "STIG" , remove it and save to .txt file
, I'm able to do it using following code:
$content | Where-Object { -not $_.Contains('STIG') } | set-content $file
Problem:
I'm not able to find word "(non-R2)" and Replace it with "non-R2" and Save values to text file.
SAMPLE:
CIS_Microsoft_Windows_Server_2008_R2_Benchmark_v3.2.0-xccdf.xml
CIS_Microsoft_Windows_Server_2012_(non-R2)_Benchmark_v2.2.0-xccdf.xml
CIS_Microsoft_Windows_Server_2012_R2_Benchmark_v2.4.0-xccdf.xml
CIS_Microsoft_Windows_Server_2016_RTM_(Release_1607)_Benchmark_v1.2.0-xccdf
CIS_Microsoft_Windows_Server_2016_STIG_Benchmark_v1.0.0-xccdf.xml
**Desired Result**
Will not contain line having "STIG" & will have replaced value "non-R2" (without brackets) and Save to Txt file:
CIS_Microsoft_Windows_Server_2008_R2_Benchmark_v3.2.0-xccdf.xml
CIS_Microsoft_Windows_Server_2012_non-R2_Benchmark_v2.2.0-xccdf.xml
CIS_Microsoft_Windows_Server_2012_R2_Benchmark_v2.4.0-xccdf.xml
CIS_Microsoft_Windows_Server_2016_RTM_(Release_1607)_Benchmark_v1.2.0-xccdf
((Get-Content -Path "sample.txt" ) -replace '\(non-R2\)','non-R2' ) | Set-Content "sample2.txt"
This will read the content of sample.txt, then replace "(non-R2)" to "non-R2", and then write the results to sample2.txt.
Related
SHORT: I am trying to duplicate lines in all files in a folder based on a certain string and then replace original strings in duplicated lines only.
Contents of the original text file (there are double quotes in the file):
"K:\FILE1.ini"
"K:\FILE1.cfg"
"K:\FILE100.cfg"
I want to duplicate the entire line 4 times only if a string ".ini" is present in a line.
After duplicating the line, I want to change the string in those duplicated lines (original line stays the same) to: for example, ".inf", ".bat", ".cmd", ".mov".
So the expected result of the script is as follows:
"K:\FILE1.ini"
"K:\FILE1.inf"
"K:\FILE1.bat"
"K:\FILE1.cmd"
"K:\FILE1.mov"
"K:\FILE1.cfg"
"K:\FILE100.cfg"
Those files are small, so using streams is not neccessary.
I am at the beginning of my PowerShell journey, but thanks to this community, I already know how to replace string in files recursively:
$directory = "K:\PS"
Get-ChildItem $directory -file -recurse -include *.txt |
ForEach-Object {
(Get-Content $_.FullName) -replace ".ini",".inf" |
Set-Content $_.FullName
}
but I have no idea how to duplicate certain lines multiple times and handle multiple string replacements in those duplicated lines.
Yet ;)
Could point me in the right direction?
To achieve this with the operator -replace you can do:
#Define strings to replace pattern with
$2replace = #('.inf','.bat','.cmd','.mov','.ini')
#Get files, use filter instead of include = faster
get-childitem -path [path] -recurse -filter '*.txt' | %{
$cFile = $_
#add new strings to array newData
$newData = #(
#Read file
get-content $_.fullname | %{
#If line matches .ini
If ($_ -match '\.ini'){
$cstring = $_
#Add new strings
$2replace | %{
#Output new strings
$cstring -replace '\.ini',$_
}
}
#output current string
Else{
$_
}
}
)
#Write to disk
$newData | set-content $cFile.fullname
}
This gives you the following output:
$newdata
"K:\FILE1.inf"
"K:\FILE1.bat"
"K:\FILE1.cmd"
"K:\FILE1.mov"
"K:\FILE1.ini"
"K:\FILE1.cfg"
"K:\FILE100.cfg"
I have a CSV file (one column/field only) with thousands of records in it.
I need a way in Powershell to search for a value using a few characters followed by a wildcard and, where found, then replace that value with a ".
I have searched around on how to do this but everyting I have found so far either doesn't cover CSV files or doesn't explain how I might be able to do the search using a wildcard.
Example of values in CSV file:
<#
RanDom.Texto 1.yellow [ Table - wood ] "gibberishcode1.moreRandomText11.xyz123+456"
R#ndomEq.Textolo 2.blue [Chair - steel ] "gibberishcode2.moreRandomText222.xyz19283+4567+89
randomi.Textpel 3.green [ counter - granite] "gibberishcode3.moreRandomText3333.xyz17243+3210+987+654"
#>
You will note above that the only values in common across the records are the .xyz in each record.
I want to replace the .xyz (and everything that follows) with a " value.
E.g. Desired result as follows:
<#
RanDom.Texto 1.yellow [ Table - wood ] "gibberishcode1.moreRandomText11"
R#ndomEq.Textolo 2.blue [Chair - steel ] "gibberishcode2.moreRandomText222"
Randomi.Textpel 3.green [ counter - granite] "gibberishcode3.moreRandomText3333"
#>
Here is some code I tried but it doesn't work in that it didn't replace the values (but it does successfuly export to a new csv file).
# Create function that gets the current file path (of where this script is located)
function Get-ScriptDirectory {Split-Path -parent $PSCommandPath}
# Create function that gets the current date and time in format of 1990-07-01_19h15m59
function Get-TimeStamp {return "{0:yyyy-MM-dd}_{0:HH}h{0:mm}m{0:ss}" -f (Get-Date)}
# Set current file path. Also used in both FOR loops below as primary source directory.
${sourceDirPath} = Get-ScriptDirectory
# Import CSV look-up file
${csvFile} = (Import-Csv -Path ${sourceDirPath}\SourceCSVFile.csv)
# for each row, replace the values of .xyz and all that follows with "
foreach(${row} in ${csvFile})
{
${row} = ${row} -replace '.xyz*','"'
}
# Set modified CSV's name and path
${newCSVFile} = ${sourceDirPath} + '\' + $(Get-TimeStamp) + '_SourceCSVFile_Modified.csv'
# export the modified CSV
${csvFile} | Export-Csv ${newCSVFile} -NoTypeInformation
I also tried this as an alternative but no luck either (i think this code below may only work for .txt files??) ...
((Get-Content -path C:\TEMP\TEST\SourceCSVFile.csv -Raw) -replace '.xyz'*,'"') | Export-Csv -Path C:\TEMP\TEST\ReplacementFile.csv
I'm new to Powershell and don't have a proper understanding of regex yet so please be gentle.
UPDATE and SOLUTION:
For those that are interested in my final solution ... I used the code provided by Thomas (Thank you!!) however my .csv file was left with some records that had a triple quote """ value at the end of the string.
As such I modified the code to use variables and execute a second pass of cleaning by replacing all triple quotation (e.g. """) values with a single quote value (e.g. ") and then piping the result to file.
# Create function that gets the current file path (of where this script is located and running from)
function Get-ScriptDirectory {Split-Path -parent $PSCommandPath}
# Set current file path
${sourceDirPath} = Get-ScriptDirectory
# Assign source .csv file name to variable
$origNameSource = 'AllNames.csv'
# Assign desired .csv file name post cleaning
$origNameCLEAN = 'AllNames_CLEAN.csv'
# First pass clean to replace .xyz* with " and assign result to tempCsvText variable
${tempCsvText} = ((Get-Content -Path ${sourceDirPath}\$origNameSource) | % {$_ -replace '\.xyz.*$', '"'})
# Second pass clean to replace """ with " and write result to a new .csv file
${tempCsvText} -replace '"""', '"' | Set-Content -Path ${sourceDirPath}\$origNameCLEAN
# Import records from new .csv file and remove duplicates by using Sort-Object * -Unique
${csvFile} = (Import-Csv -Path ${sourceDirPath}\$origNameCLEAN) | Sort-Object * -Unique
First, a .csv file is nothing else than a regular text file, just following some rules on how content is embedded (one line for each row, columns delimited by a defined ASCII character, optional header). Your last line is close. You have to use a regular expression, that reaches until the end of a line. This will do it:
Get-Content -Path C:\TEMP\TEST\SourceCSVFile.csv | % {$_ -replace '\.xyz.*$', '"'} | Set-Content -Path C:\TEMP\TEST\ReplacementFile.csv
Differences:
I removed the -Raw parameter to get each line as one string.
I used the pipe to process each string (line)
I adjusted your regex to match from .xyz until the end of each line
I piped the result to Set-Content as I only did text replacement and did not read any objects that would then have to be retranslated back to csv text by Export-Csv
I want to add text into specific line of txt file. I can't find any solution on internet.
This code adds text in further line (I want for example second line):
$test_out = "test"
$test_out | Add-Content "C:\tmp\test.txt"
If you want to add text to the end of a specific line, you can do it like this
$fileContent = Get-Content $filePath
$fileContent[$lineNumber-1] += $textToAdd
$fileContent | Set-Content $filePath
If you want to replace the text instead of adding, just remove the '+' sign.
You do of course have to set the variables
$filePath, $textToAdd and $lineNumber first.
Here a solution which reads the content of the file and access the line using the array index (-1). This example adds the line test and a line break to the second line.
$filePath = 'C:\tmp\test.txt'
$test_out = "test"
$fileContent = Get-Content -Path $filePath
$fileContent[1] = "{0}`r`n{1}" -f $test_out, $fileContent[1]
$fileContent | Set-Content $filePath
Hi I'm trying to change the letters in various files (which I have in listed in a text file) I can go through the files individually using the command below, but I was wondering if there's a way to loop through the list amending each of the file contents.
example I'd like to change test-pop-test to test-bar-test and this is the content of several files, not the name of the file.
The code I am using is below, amending the names before running.
(Get-Content c:\temp\list.txt) | ForEach-Object { $_ -replace "pop", "bar" } | Set-Content c:\temp\test2.txt
Each object is a text file that I would like it to loop through, so list.txt contains a list of text files where the contents are to be amended, not sure if I explained this very well.. :)
Thanks in advance :)
A basic example:
$Temp = Get-ChildItem C:\Temp -Force
ForEach ($f in $Temp)
{
(Get-Content $f) |
% { $_ -replace 'pop', 'bar' } |
Set-Content $f
}
I'm trying to find out how to use powershell to find and delete lines without certain string pattern in a set of files. For example, I have the following text file:
111111
22x222
333333
44x444
This needs to be turned into:
22x222
44x444
given that the string pattern of 'x' is not in any of the other lines.
How can I issue such a command in powershell to process a bunch of text files?
thanks.
dir | foreach { $out = cat $_ | select-string x; $out | set-content $_ }
The dir command lists the files in the current directory; the foreach goes through each file; cat reads the file and pipes into select-string; select-string finds the lines that contains the specific pattern, which in this case is "x"; the result of select-string is stored in $out; and finally, $out is written to the same file with set-content.
We need the temporary variable $out because you cannot read and write the same file at the same time.
This will process all txt files from the working directory. Each file content is checked and only lines that have 'x' in them are allowed to pass on. The result is written back to the file.
Get-ChildItem *.txt | ForEach-Object{
$content = Get-Content $_.FullName | Where-Object {$_ -match 'x'}
$content | Out-File $_.FullName
}