Powershell - export csv value into specific column - powershell

Having some issues with the syntax. I'm trying to copy the variable value into another csv column.
$file1 = import-csv C:\temp\csv1.csv
$file2 = import-csv C:\Temp\csv2.csv
$file3 = import-csv C:\Temp\csv3.csv
foreach ($line in $file1) {
foreach ($row in $file2) {
if ($line.col1 -eq $row.col1){
#this is the part im having issues with:
$row.col2 = $line.col3 | Export-Csv #???
}
}
}

$row is a reference to an object in $file2. When you update $row, $file2 is automatically updated. Therefore, you can just wait until you have made all your updates before exporting to CSV. So assuming your logic is correct for when you want to update col2 of $file2, you can do the following:
$file1 = import-csv C:\temp\csv1.csv
$file2 = import-csv C:\Temp\csv2.csv
foreach ($line in $file1) {
foreach ($row in $file2) {
if ($line.col1 -eq $row.col1) {
$row.col2 = $line.col3
}
}
}
$file2 | Export-Csv -Path NewFile.Csv -NoType

Related

How to update cells in csv one by one without knowing column names

I try to replace some texts inside a csv like following:
$csv = Import-Csv $csvFileName -Delimiter ';'
foreach ($line in $csv)
{
$properties = $line | Get-Member -MemberType Properties
for ($i = 0; $i -lt $properties.Count;$i++)
{
$column = $properties[$i]
$value = $line | Select -ExpandProperty $column.Name
# Convert numbers with , as separator to . separator
if ($value -match "^[+-]?(\d*\,)?\d+$")
{
$value = $value -replace ",", "."
# HOW TO update the CSV cell with the new value here???
# ???
}
}
}
$csv | Export-Csv $csvFileName -Delimiter ',' -NoTypeInformation -Encoding UTF8
As you can see, I miss the line where I want to update the csv line's cell value with the new value => can someone tell me how I can do that?
Assuming the regex you have in place will match the pattern you expect, you can simplify your code using 2 foreach loops, easier than a for. This method invokes the intrinsic PSObject member, available to all PowerShell objects.
$csv = Import-Csv $csvFileName -Delimiter ';'
foreach ($line in $csv) {
foreach($property in $line.PSObject.Properties) {
if ($property.Value -match "^[+-]?(\d*\,)?\d+$") {
# regex operator not needed in this case
$property.Value = $property.Value.Replace(",", ".")
}
}
}
$csv | Export-Csv ....
You can also do all process in pipeline (method above should be clearly faster, however this method is likely to be memory friendlier):
Import-Csv $csvFileName -Delimiter ';' | ForEach-Object {
foreach($property in $_.PSObject.Properties) {
if ($property.Value -match "^[+-]?(\d*\,)?\d+$") {
# regex operator not needed in this case
$property.Value = $property.Value.Replace(",", ".")
}
}
$_ # => output this object
} | Export-Csv myexport.csv -NoTypeInformation

converting data from text to CSV and modifying it in Powershell

There is a data in my text file. It is a list of IP addresses in column, I want to convert it into csv file and with that also i want to create 3 more columns and put the same data that is present in the first column
so far have created this
$output_file= "D:\output.csv"
#the headers i have given below
Set-Content D:\output.csv 'record,stream,library,thumbnail'
$input_file= "D:\input1.txt"
$lines = Get-Content $input_file
foreach ($line in $lines) {
Add-Content -Path $output_file -Value "$line, $line, $line, $line"
}
Why not go the object way?
$output_file = "D:\output.csv"
$input_file = "D:\input1.txt"
Get-Content -Path $input_file | ForEach-Object {
# output an object
[PsCustomObject]#{
record = $_
stream = $_
library = $_
thumbnail = $_
}
} | Export-Csv -Path $output_file -NoTypeInformation

Manipulate CSV value without knowing column names [duplicate]

I want to process a csv file in powershell, but I don't know what the column headings in the CSV file will be when it is processed.
For example:
$path = "d:\scratch\export.csv"
$csv = Import-csv -path $path
foreach($line in $csv)
{
foreach ($head in $line | get-member | where-object {$_.MemberType -eq "NoteProperty"} | select Definition)
{
#pseudocode...
doSomething($head.columnName, $head.value)
}
}
How do I loop through the line in the csv file, getting the name of the column and the value? Or is there another way I should be doing this (like not using Import-csv)?
Import-Csv $path | Foreach-Object {
foreach ($property in $_.PSObject.Properties)
{
doSomething $property.Name, $property.Value
}
}
A slightly other way of iterating through each column of each line of a CSV-file would be
$path = "d:\scratch\export.csv"
$csv = Import-Csv -path $path
foreach($line in $csv)
{
$properties = $line | Get-Member -MemberType Properties
for($i=0; $i -lt $properties.Count;$i++)
{
$column = $properties[$i]
$columnvalue = $line | Select -ExpandProperty $column.Name
# doSomething $column.Name $columnvalue
# doSomething $i $columnvalue
}
}
so you have the choice: you can use either $column.Name to get the name of the column, or $i to get the number of the column
$header3 = #("Field_1","Field_2","Field_3","Field_4","Field_5")
Import-Csv $fileName -Header $header3 -Delimiter "`t" | select -skip 3 | Foreach-Object {
$record = $indexName
foreach ($property in $_.PSObject.Properties){
#doSomething $property.Name, $property.Value
if($property.Name -like '*TextWrittenAsNumber*'){
$record = $record + "," + '"' + $property.Value + '"'
}
else{
$record = $record + "," + $property.Value
}
}
$array.add($record) | out-null
#write-host $record
}

powershell: replacing string using hash table

I have files which need to be modified according to mapping provided in CSV. I want to read each line of my txt file and depending if specified value exist I want to replace other strings in that line according to my CSV file (mapping). For that purpose I have used HashTable. Here is my ps script:
$file ="path\map.csv"
$mapping = Import-CSV $file -Encoding UTF8 -Delimiter ";"
$table = $mapping | Group-Object -AsHashTable -AsString -Property Name
$original_file = "path\input.txt"
$destination_file = "path\output.txt"
$content = Get-Content $original_file
foreach ($line in $content){
foreach ($e in $table.GetEnumerator()) {
if ($line -like "$($e.Name)") {
$line = $line -replace $e.Values.old_category, $e.Values.new_category
$line = $line -replace $e.Values.old_type, $e.Values.new_type
}
}
}
Set-Content -Path $destination_file -Value $content
My map.csv looks as follows:
Name;new_category;new_type;old_category;old_type
alfa;new_category1;new_type1;old_category1;old_type1
beta;new_category2;new_type2;old_category2;old_type2
gamma;new_category3;new_type3;old_category3;old_type3
And my input.txt content is:
bla bla "bla"
buuu buuu 123456 "test"
"gamma" "old_category3" "old_type3"
alfa
When I run this script it creates exactly the same output as initial file. Can someone tell me why it didn't change the line where "gamma" appears according to my mapping ?
Thanks in advance
Couple of things to change.
Firstly there is no need to change $mapping to a hash, Import-Csv already gives you an object array to work with.
Secondly, if you want to update the elements of $content, you need to use a for loop such that you can directly access modify them. Using a foreach creates a new variable in the pipeline and you were previously modifying it but then never writing it back to $content
Below should work:
$file ="map.csv"
$mapping = Import-CSV $file -Encoding UTF8 -Delimiter ";"
$original_file = "input.txt"
$destination_file = "output.txt"
$content = Get-Content $original_file
for($i=0; $i -lt $content.length; $i++) {
foreach($map in $mapping) {
if ($content[$i] -like "*$($map.Name)*") {
$content[$i] = $content[$i] -replace $map.old_category, $map.new_category
$content[$i] = $content[$i] -replace $map.old_type, $map.new_type
}
}
}
Set-Content -Path $destination_file -Value $content

Compare 2 csv to create list of unique items in Powershell

I have 2 csv files and need to create a 3rd.
csv_1 (only 1 column)
USERNAME
guy1
guy2
guy3
csv_2
"ID","USERNAME","GROUPU"
"1","guyA","Default"
"2","guy1","Default"
"3","guyB","Default"
"4","guy3","Default"
"5","guyC","Default"
for an output from comparing these two tables I'd like to see:
USERNAME,ID
guy1,2
guy3,4
I tried this and it dumped far too much data (listing all entries multiple times)
$file1 = Import-Csv csv_1.csv
$file2 = Import-Csv csv_2.csv
foreach ($line in $file1){
$U1 = $line.User
foreach ($line in $file2)
$U2 = $line.USERNAME
$I2 = $line.ID
If ($U1 = $U2){
$x = $U2+","+$I2
ac temp.csv$x
}
}
}
I added a break:outside line after the ac temp.csv $x line but then it only listed 1 entry multiple times.
I also tries this (based on this entry):
$file1 = Import-Csv csv_1.csv
$file2 = Import-Csv csv_2.csv
ForEach($Record in $file1){
$MatchedValue = (Compare-Object $file2 $Record -Property "USERNAME" -IncludeEqual -ExcludeDifferent -PassThru).value
$Record = Add-Member -InputObject $Record -Type NoteProperty -Name "SQLID" -Value $MatchedValue
}
$file1 #|Export-Csv ".\Combined.csv" -NoTypeInformation
but didn't get anything in the SQLID column and it included some values in $file1 that are not in $file2. I figure the lack of SQLID value is because I need to add a variable there (the -value just being $matchedValue which is just the line from $file1), but I'm not sure how to get the variable from the correct record in $file2.
Suggestions?
For each entry in $file1, test if an entry in $file2 has the same USERNAME property value. If so, select the USERNAME and ID Properties and add the entry to a collection that you can write back to the final csv file:
$file1 = Import-Csv .\csv_1.csv
$file2 = Import-Csv .\csv_2.csv
$users = #()
foreach($u in $file1)
{
$u2 = $file2 |Where-Object {$_.USERNAME -eq $u.USERNAME}|Select USERNAME,ID -First 1
if($u2)
{ $users += $u2 }
}
$users|Export-Csv -Path .\csv_3.csv -NoTypeInformation -Force