merge several .csv files into one array - powershell

I'm trying to load several .csv files (with the same columns) into the same array from different directories.
$csv1 = Import-Csv "PATH1"
$csv1 = Import-Csv "PATH2"
$csv1 | Export-Csv C:\test.csv
This just outputs the last .csv loaded, what would be the best way to do this?

When in doubt, read the documentation. The Import-Csv cmdlet accepts an array of path strings as input, so all you need to do (assuming that all your CSVs have the same fields) is something like this:
$src = 'C:\path\to\input1.csv', 'C:\path\to\input2.csv', ...
$dst = 'C:\path\to\output.csv'
Import-Csv $src | Export-Csv $dst -NoType
If you want an additional column with the path of the source file you need some additional steps, though:
$src | ForEach-Object {
$path = $_
Import-Csv $path | Select-Object *,#{n='Path';e={$path}}
} | Export-Csv $dst -NoType

Related

how to prepend filename to every record in a csv?

How do we prepend the filename to ALL the csv files in a specific directory?
I've got a bunch of csv files that each look like this:
ExampleFile.Csv
2323, alex, gordon
4382, liza, smith
The output I'd like is:
ExampleFile.Csv, 2323, alex, gordon
ExampleFile.Csv, 4382, liza, smith
How do we prepend the filename to ALL the csv files in a specific directory?
I've attempted the following solution:
Get-ChildItem *.csv | ForEach-Object {
$CSV = Import-CSV -Path $_.FullName -Delimiter ","
$FileName = $_.Name
$CSV | Select-Object *,#{E={$FileName}} | Export-CSV $_.FullName -NTI -Delimiter ","
}
However, this did not work because it was altering the first row. (My data does not have a header row). Also, this script will append to each record at the end rather than prepend at the beginning.
You're missing the column header name I think. Take a look at the duplicate (or original, rather) and see Shay's answer. Your Select-Object should look like:
$CSV | Select-Object #{Name='FileName';Expression={"$filename"}},* | Export-Csv -Path $FileName -NoTypeInformation -Delimiter ','
That worked fine for me with multiple CSVs in a directory when using the rest of your sample code verbatim.
If your files do not have headers and the column count is unknown or unpredictable, you can read each line with Get-Content, make the changes, and then use Set-Content to make the update.
Get-ChildItem *.csv | ForEach-Object {
$Filename = $_.Name
$Fullname = $_.FullName
$contents = Get-Content -Path $Fullname | Foreach-Object {
"{0}, {1}" -f $Filename,$_
}
$contents | Set-Content -Path $Fullname
}

Merges csv files from directory into a single csv file PowerShell

How can I run one single PowerShell script that does the following in series?
Adds a the filename of all csv files in a directory as a column in the end of each file using this script:
Get-ChildItem *.csv | ForEach-Object {
$CSV = Import-CSV -Path $_.FullName -Delimiter ","
$FileName = $_.Name
$CSV | Select-Object *,#{N='Filename';E={$FileName}} | Export-CSV $_.FullName -NTI -Delimiter ","}
Merges all csv files in the directory into a single csv file
Keeping only a header (first row) only from first csv and excluding all other first rows from files.
Similiar to what kemiller2002 has done here, except one script with csv inputs and a csv output.
Bill's answer allows you to combine CSVs, but doesn't tack file names onto the end of each row. I think the best way to do that would be to use the PipelineVariable common parameter to add that within the ForEach loop.
Get-ChildItem \inputCSVFiles\*.csv -PipelineVariable File |
ForEach-Object { Import-Csv $_ | Select *,#{l='FileName';e={$File.Name}}} |
Export-Csv \outputCSVFiles\newOutputFile.csv -NoTypeInformation
That should accomplish what you're looking for.
This is the general pattern:
Get-ChildItem \inputCSVFiles\*.csv |
ForEach-Object { Import-Csv $_ } |
Export-Csv \outputCSVFiles\newOutputFile.csv -NoTypeInformation
Make sure the output CSV file has a different filename pattern, or use a different directory name (like in this example).
If your csv files dont have always same header you can do it :
$Dir="c:\temp\"
#get header first csv file founded
$header=Get-ChildItem $Dir -file -Filter "*.csv" | select -First 1 | Get-Content -head 1
#header + all rows without header into new file
$header, (Get-ChildItem $Dir -file -Filter "*.csv" | %{Get-Content $_.fullname | select -skip 1}) | Out-File "c:\temp\result.csv"

Import specified columns from CSV, by header name, and export to new file

I want to make a ps1 that takes all .csv in a folder, pulls out all values under 2 columns (identified by header), then spits out new .csv for each file with only these two columns.
I can make it work on individual files, below, but when I add a wildcard it says function doesn't work on multiple files. I have tried other methods but I don't have a formal CS background (so my "script" below might seem rudimentary); I get close but nothing is working so far.
$inputpath = 'C:/Users/AAA/AAA/AAA/AAA/'
$inputfile = 'BBB.csv'
$outputpath = $inputpath
$outputfile = $inputfile.basename + 'edited' + '.csv'
Import-Csv $inputpath$inputfile |
select COLUMNtitle1, COLUMNtitle2 |
Export-Csv -Path $outputpath$outputfile -NoTypeInformation
echo
Since you aren't using Get-ChildItem for $inputfile then there isn't a basename property. Also it's safer to use Join-Path when joining paths and better to avoid + to concatenate strings.
$inputfolder = 'C:\Users\AAA\AAA\AAA\AAA\'
Get-ChildItem $inputfolder -include *.csv | % {
$outputpath = Join-Path $inputfolder "$($_.basename)edited.csv"
Import-Csv $_.fullname | select COLUMNtitle1,COLUMNtitle2 | Export-Csv -Path $outputpath -NoTypeInformation
}

Using Powershell to export to CSV with columns

I am trying to do a simple script that pulls in the name of the file and the contents of said text file into a CSV file. I am able to pull in all of the information well enough but it's not splitting up into different columns in the CSV file. When I open up the CSV file in excel everything is in the first column, and I need the two bits of information separated into separate columns. So far my working code is as follows:
$Data = Get-ChildItem -Path c:path -Recurse -Filter *.txt |
where {$_.lastwritetime -gt(Get-Date).addDays`enter code here`(-25)}
$outfile = "c:path\test.csv"
rm $outfile
foreach ($info in $Data) {
$content = Get-Content $info.FullName
echo "$($info.BaseName) , $content" >> $outfile
}
I figured out how to seperate the information by rows but I need it by columns. I'm new to powershell and can't seem to get past this little speed bump. Any input would be greatly appreciated. Thanks in advance!
Output:
Itm# , TextContent
Itm2 , NextTextContent
What I need:
Itm# | Text Content |
Itm2 | NextTextContent |
Except for a few syntactical errors your code appears to be working as expected. I worry if you are having issues in Excel with you text import. I touched up your code a bit but it is functionally the same as what you had.
$Data = Get-ChildItem -Path "C:\temp" -Recurse -Filter *.txt |
Where-Object {$_.LastWriteTime -gt (Get-Date).addDays(-25)}
$outfile = "C:\temp\test.csv"
If(Test-Path $outfile){Remove-Item $outfile -Force}
foreach ($info in $Data) {
$content = Get-Content $info.FullName
"$($info.BaseName) , $content" | Add-Content $outfile
}
I don't know what version of Excel you have but look for the text import wizard.
Do you mean something like this?
Get-ChildItem -Path C:\path -Recurse -Filter *.txt |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-25) } | ForEach-Object {
New-Object PSObject -Property #{
"Itm#" = $_.FullName
"TextContent" = Get-Content $_.FullName
} | Select-Object Itm#,TextContent
} | Export-Csv List.csv -NoTypeInformation
Excel will treat the data in csv files which are delimited bij the ; as a single columns.
I always use the -delimiter switch on export-csv or convertto-csv to set this as a delimiter.

Merge Files over multiple folders using PowerShell

I have a directory structure as below.
Root_dir
Sub_dir1
Sub_dir2
....
Here I have multiple sub folders in the Root directory. Now each sub folder contains a message.csv file. I want to append them and create a new csv file.
Assuming that all CSVs have the same columns something like this should work:
$root = 'C:\path\to\Root_dir'
$csv = 'C:\path\to\output.csv'
Get-ChildItem $root -Filter 'message.csv' -Recurse | % {
Import-Csv $_.FullName
} | Export-Csv $csv -NoTypeInformation
To remove duplicates from the output try this instead:
$root = 'C:\path\to\Root_dir'
$csv = 'C:\path\to\output.csv'
Get-ChildItem $root -Filter 'message.csv' -Recurse | % {
Import-Csv $_.FullName
} | ConvertTo-Csv -NoTypeInformation | select -Unique | Out-File $csv