Close open CSV before writing data back to it. Powershell - powershell

I have a csv file like so:
$csv = Import-Csv "C:\data.csv"
Followed by code that formats the csv data.
When I write to the file
$csv | Export-Csv -path "C:\data.csv" -NoType
If the file is open I get (predictably)
**Export-Csv : The process cannot access the file 'C:\data.csv' because it is being used by another process.**
There are times the file may be saved yet remain open when interacting with the script. I'd like to efficiently check for the open file and close it so I can write the data back to the same file/variable.

Ideally there is nothing like closing file in Powershell as it handles it automatically. Below code worked for me
$csv = Import-Csv "C:\data.csv"
$csv | Export-Csv -path "C:\data.csv" -NoType

Related

PowerShell: How to upload data from multiple txt files into a single xlsx or csv file

PowerShell: How to upload data from multiple txt files into a single xlsx or csv file using Windows PowerShell
I would like to be able to use a loop that will iterate through a folder of many txt files and upload all of the data from them into a single xlsx or csv file.
The txt files are tab delimited with a few columns and include column headers. I only want the headers to upload to the new file once so it shows up at the top but never again.
I found the following code on another site that allows me to upload multiple files into a single one and only uploads the header once. The issue is that the data does not format correctly as the rows are put into a single cell when I need each point to be split up.
$getFirstLine = $true
get-childItem "YOUR_DIRECTORY\*.txt" | foreach {
$filePath = $_
$lines = $lines = Get-Content $filePath
$linesToWrite = switch($getFirstLine) {
$true {$lines}
$false {$lines | Select -Skip 1}
}
$getFirstLine = $false
Add-Content "YOUR_DESTINATION_FILE" $linesToWrite
}
This image is an example of the txt data with the first row being the column headers:
txt file data that I am trying to upload into a csv or xlsx
If you're certain the text files all have the same format, you can treat them as tab-delimited csv files, import them and save out merged like below:
(Get-ChildItem -Path 'X:\Somewhere' -Filter '*.txt' -File).FullName |
Import-Csv -Delimiter "`t" |
Export-Csv 'X:\SomewhereElse\merged.csv' -UseCulture -NoTypeInformation
Using switch -UseCulture means the merged csv is written out using the delimiter your local Excel expects, so when done just double-click the file to open in Excel.

Using Powershell to write out two header rows without deleting existing data

I have a need to generate two header rows to an existing csv file because the system where the csv will be uploaded needs the two header rows. The csv file will contain data that I want to keep.
I have been testing a powershell script to do this, and I can write a single row of headers, but am struggling to write two rows.
Below is the powershell script I am currently trying to build out.
$file = "C:\Users\_svcamerarcgis\Desktop\Test.csv"
$filedata = import-csv $file -Header WorkorderETL 'n ICFAORNonICFA, WONUmber, Origin
$filedata | export-csv $file -NoTypeInformation
The end result I'm looking for should be as follows:
WorkorderETL
ICFAORNonICFA, WONUmber, Origin
xxx,yyy,zzz
The sole purpose of Import-Csv's -Header parameter is to provide an array of column names to serve as the property names of the custom objects that the CSV rows are parsed into - you cannot repurpose that for special output formatting for later exporting.
You can use the following approach instead, bypassing the need for Import-Csv and Export-Csv altogether (PSv5+):
$file = 'C:\Users\User\OneDrive\Scripts\StackTesting\Test.csv'
# Prepend the 2-line header to the existing file content
# and save it back to the same file
# Adjust the encoding as needed.
#'
WorkorderETL
ICFAORNonICFA,WONUmber,Origin
'# + (Get-Content -Raw $file) | Set-Content $file -NoNewline -Encoding utf8
To be safe, be sure to create a backup of the original file first.
Since the file is being read (in full) and rewritten in the same pipeline, there's a hypothetical chance of data loss if writing back to the input file get interrupted.
You may be better trying to handle this as a text file, considering you are just trying to add a single line at the top of the CSV:
$file = "C:\Users\User\OneDrive\Scripts\StackTesting\Test.csv"
$CSV = "c1r1, c2r1, c3r1 `nc1r2, c2r2, c3r2"
$filedata = Get-Content $file
$filedata = "WorkorderETL`n" + $CSV
$filedata | Out-File $file
This will resul in the CSV file holding:
WorkorderETL
c1r1, c2r1, c3r1
c1r2, c2r2, c3r2
Which looks to be what you want.

Filtering data from CSV file with PowerShell

I have huge csv file where first line contains headers of the data. Because the file size I can't open it with excel or similar. I need to filter rows what I only need. I would want to create new csv file which contains only data where Header3 = "TextHere". Everything else is filtered away.
I have tried in PowerShell Get-Content Select-String | Out-File 'newfile.csv' but it lost header row and also messed up with the data putting data in to wrong fields. There is included empty fields in the data and I believe that is messing it. When I tried Get-Content -First or -Last data seemed to be in order.
I have no experience handling big data files or powershell before. Also other options besides PowerShell is also possible if it is free to use as "non-commercial use"
try like this (modify your delimiter if necessary):
import-csv "c:\temp\yourfile.csv" -delimiter ";" | where Header3 -eq "TextHere" | export-csv "c:\temp\result.csv" -delimiter ";" -notype

Code to Open File, Select All and Copy

I am trying to create a script that will open up a .txt file and select and then copy the data in the .txt file. I am able to open the .txt file but what I am not able to do is create a script to open, select and copy at the same time and in the same script line.
Here are some code examples that I have tried:
Invoke-Item adddata.txt; object.SendKeys "^(a)"
Invoke-Item adddata.txt; WshShell.SendKeys "^"; WshShell.SendKeys "a"
Invoke-Item adddata.txt; WshShell.SendKeys "{^}a"
What happens is the file does open up but nothing selects/copies on either example.
I think the Get-Content cmdlet is what you should be using:
Get-Content -Path "C:\ExampleFolder\adddata.txt" | clip
I think php123's answer does the job, however because your paste target is Excel and if the data in your file is in columns with a delimiter and you can improve the final result. You need to use the Import-Csv cmdlet to convert to an object and then use the ConvertTo-Csv to turn you object into a tab delimited string which will then paste nicely into Excel. Something like this assuming your file is comma separated:
Import-Csv "C:\ExampleFolder\adddata.txt" -Delimiter ',' | ConvertTo-Csv -Delimiter "`t" | clip

Append filename to CSV in new column

I have a lot of csv files stored in a directory.
In each csv file need to add the name as column this through powershell.
Example
File location: <SERVERNAME>\Export\FILENAME1.CSV
Contents:
1232;Description;a1
1232;Description;a2
The result must be:
1232;Description;a1;FILENAME1.CSV
1232;Description;a2;FILENAME1.CSV
Can someone help me with this?
The following will append a Filename column to each .CSV file in a directory:
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 ";"
}
Explanation:
Uses Get-ChildItem to get all files named *.csv
Iterates through each file with ForEach-Object and uses Import-CSV to load their contents as a PowerShell object
Records the name of the file in $FileName
Uses Select-Object to add a calculated property with the name Filename and the value of the $FileName variable
Uses Export-CSV to write back over the original file. The -NTI (NoTypeInformation) switch is used to ensure the PowerShell object header line is not included.
Mark Wragg's PowerShell code works, but I had to change the delimiter to , instead of ; so that it opens in Excel. I'm trying to figure out how to append the filename to the first column instead of the last because my files don't have the same number of fields so they don't align.