Powershell script Export-CSV cutoff characters in a string of a .TXT files with Comma - string

1 .. $Count | ForEach-Object {
$i = $_.ToString($Length)
$Offset = $BatchSize * ($_ - 1)
$outputFile = $ParentDirectory + "\" + $strBaseName + "-" + $i + $strExtension
If($_ -eq 1) {
$objFile | Select-Object -First $BatchSize | Export-Csv $outputFile -NoTypeInformation -Encoding UTF8
} Else {
$objFile | Select-Object -First $BatchSize -Skip $Offset | Export-Csv $outputFile -NoTypeInformation -Encoding UTF8
}
}
I have a .txt with a comma on row 3 below. My code is stripping anything after the comma as seen below. how do I fix it? My file is pipe delimited.
Original file contains
|Header1|Header2|Header3|Header4|
|320|A1| |0900|
|320|A2|This, comma is needed|0900|
|320|A3| |0700|
|320|A4|f2|0900|
|320|A5| |0700|
|320|L2|c6|0900|
After splitting into 2 files -notice the missing text after "this,"
file1
|Header1|Header2|Header3|Header4|
|320|A1| |0900|
|320|A2|This,
|320|A3| |0700|
file2
|Header1|Header2|Header3|Header4|
|320|A4|f2|0900|
|320|A5| |0700|
|320|L2|c6|0900|
Please advise. Thanks
I tried to use delimiter and replace commands. Didn't work

It looks like when you imported your delimited file into $objFile, you forgot to pass -Delimiter '|' to the Import-Csv call, which would not interpret your |-separated file properly, given that Import-Csv - as well as Export-Csv - default to , as the separator.
Thus, the solution is to use -Delimiter '|' in both your Import-Csv and Export-Csv calls.
As for what you tried:
Here's a minimal example that demonstrates the problem with omitting -Delimiter '|', using the in-memory CSV processing cmdlets, ConvertFrom-Csv and ConvertTo-Csv:
#'
Field1|Field2
Value1|Value2, and more
'# |
ConvertFrom-Csv |
ConvertTo-Csv
Output (note the missing , and more part, and how the output lines as a whole are double-quoted):
"Field1|Field2"
"Value1|Value2"
Since header row Field1|Field2 contains no , it became a single property in the resulting objects, literally named Field1|Field2.
Since the data row happened to contain , it was parsed as two fields, and since there is only one column, the extra field was simply discarded.

Related

Manipulate strings in a txt file with Powershell - Search for words in each line containing "." and save them in new txt file

I have a text file with different entries. I want to manipulate it to filter out always the word, containing a dot (using Powershell)
$file = "C:\Users\test_folder\test.txt"
Get-Content $file
Output:
Compass Zype.Compass 1.1.0 thisisaword
Pomodoro Logger zxch3n.PomodoroLogger 0.6.3 thisisaword
......
......
......
Bla Word Program.Name 1.1.1 this is another entry
As you can see, in all lines, the "second" "word" contains a dot, like "Program.Name".
I want to create a new file, which contains just those words, each line one word.
So my file should look something like:
Zype.Compass
zxch3n.PomodoroLogger
Program.Name
What I have tried so far:
Clear-Host
$folder = "C:\Users\test_folder"
$file = "C:\Users\test_folder\test.txt"
$content_txtfile = Get-Content $file
foreach ($line in $content_textfile)
{
if ($line -like "*.*"){
$line | Out-File "$folder\test_filtered.txt"
}
}
But my output is not what I want.
I hope you get what my problem is.
Thanks in advance! :)
Here is a solution using Select-String to find sub strings by RegEx pattern:
(Select-String -Path $file -Pattern '\w+\.\w+').Matches.Value |
Set-Content "$folder\test_filtered.txt"
You can find an explanation and the ability to experiment with the RegEx pattern at RegEx101.
Note that while the RegEx101 demo also shows matches for the version numbers, Select-String gives you only the first match per line (unless argument -AllMatches is passed).
This looks like fixed-width fields, and if so you can reduce it to this:
Get-Content $file | # Read the file
%{ $_.Substring(29,36).Trim()} | # Extract the column
?{ $_.Contains(".") } | # Filter for values with "."
Set-Content "$folder\test_filtered.txt" # Write result
Get-content is slow and -like is sometimes slower than -match. I prefer -match but some prefer -like.
$filename = "c:\path\to\file.txt"
$output = "c:\path\to\output.txt"
foreach ($line in [System.IO.File]::ReadLines($filename)) {
if ($line -match "\.") {
$line | out-file $output -append
}
}
Otherwise for a shorter option, maybe
$filename = "c:\path\to\file.txt"
$output = "c:\path\to\output.txt"
Get-content "c:\path\to\file.txt" | where {$_ -match "\.") | Out-file $output
For other match options that are for the first column, either name the column (not what you do here) or use a different search criteria
\. Means a period anywhere seein the whole line
If it's all periods and at the beginning you can use begining of line so..
"^\." Which means first character is a period.
If it's always a period before the tab maybe do an anything except tab period anything except tab or...
"^[^\t]*\.[^\t]*" this means at the start of the line anything except tab any quantity then a period then anything except a tab any number of times.

Excel/Powershell start a loop from row 2

Actually I have this loop :
foreach($line in Get-Content .\script2.csv)
{ $firstname = $line.split(';')[0]
$lastname = $line.split(';')[1]
$email = $line.split(';')[2]
$newLine = "$firstname,""$lastname"",""$email"""
$newLine >> newCSV.csv }
I use it to extract data and paste it in a correct format.
I would like to know what is the correct syntax to start it from the row 2 and not taking all my sheet ?
Thanks !
Use Select -Skip $N to skip the first $N items of a collection:
foreach($line in Get-Content .\script2.csv |Select -Skip 1)
{
$firstname = $line.split(';')[0]
$lastname = $line.split(';')[1]
$email = $line.split(';')[2]
$newLine = "$firstname,""$lastname"",""$email"""
$newLine >> newCSV.csv
}
If what you want to do is to convert a CSV file that uses the semi-colon ; as delimiter to a new Csv file that uses the comma , as delimiter, and in the process remove the header line from it, you can do:
Import-Csv -Path 'D:\Test\blah.csv' -Delimiter ';' | ConvertTo-Csv -NoTypeInformation |
Out-String -Stream | Select-Object -Skip 1 | Set-Content -Path 'D:\Test\newCSV.csv'

Powershell Export-CSV formatting

I'm exporting data from multiple paths from our network drives. If a document is older than a certain date, I export it to a CSV file. But when I open up Excel, theres no formatting. Everything is all jammed up in the "A" column. I would like the "Name" to be in column A, "LastWriteTime" to be in column B, etc.
Here is my code:
foreach($path in $SharedFolder)
{
Get-ChildItem -Path $path -Recurse | Where-Object {!$_.PSIsContainer -and $_.LastWriteTime -lt $DateLimit} |
Select-Object Name, LastWriteTime, LastAccessTime, Length, DirectoryName |
Export-Csv -Path $HOME\Desktop\ExcelDoc.csv -NoTypeInformation
}
Any help would be appreciated.
Setting the delimiter to the system default delimiter should take care of this.
You can do this by adding -Delimiter to your command with the character specified.
For example: -Delimiter ';'

Excel CSV files delimiter change

I'm creating in Excel a sub-folder in a directory and save there multiple CSV-files from a Excel Workbook
My problem is that I need to do this on a system where the list separator is a ','. The CSV files are getting read from a system where the default list separator is a ';'. I cannot change this
So I need to change the ',' in the CSV files into a ';'. My idea is to achieve this using PowerShell.
My first attempt was to change the delimiter of the CSV immediately after creating it in excel by passing to a script the file-name. I manage to change the delimiter for a certain file but I struggle to pass the pathname to the script (no error but also no change in the file):
Script Code:
param([string]$path)
$content = [IO.File]::ReadAllText($path) #readParameter
Import-CSV -Path $content -Delimiter ','|Export-CSV -Path C:\Users\Desktop\temp.csv -Delimiter ';' -NoTypeInformation #Export a CSV-File with ;
(Get-Content C:\Users\Desktop\temp.csv) | % {$_ -replace '"', ""} | out-file -FilePath C:\Users\Desktop\temp.csv -Force -Encoding ascii #remove " from file
Remove-Item -Path $content #remove old CSV-file
Rename-Item -Path C:\Users\Desktop\temp.csv -NewName $content #change file name
Excel Call:
Call Shell("powershell.exe -ExecutionPolicy Unrestricted -File C:\Users\Desktop\delimiterChange.ps1 -path """ & location & """", 1)
Thank You
If you want to use PS, this is the easy quick and dirty. Works like a charm.
$csv = Import-csv "C:\initial.csv"
$csv | Export-Csv "C:\converted.csv" -NoClobber -NoTypeInformation -Delimiter ";"
param([string]$path)
$content = [IO.File]::ReadAllText($path) #readParameter
Import-CSV -Path $content -Delimiter ','|Export-CSV -Path C:\Users\Desktop\temp.csv -Delimiter ';' -NoTypeInformation
Your code reads the content of the CSV (assuming that the path to the CSV is passed via the parameter -Path) and tries to pass that as the path to Import-Csv. Change the above to this:
param([string]$path)
Import-CSV -Path $path |
Export-CSV -Path C:\Users\Desktop\temp.csv -Delimiter ';' -NoType
You can even replace the content of the file if you run Import-Csv in an expression:
(Import-Csv -Path $path) |
Export-Csv -Path $path -Delimiter ';' -NoType
I'd recommend keeping the double quotes, but if you must remove them you can do that in the pipeline like this:
(Import-Csv -Path $path) |
ConvertTo-Csv -Delimiter ';' -NoType |
% { $_ -replace '"', '' } |
Set-Content -Path $path
In Control Panel > Regional Settings > Additional Settings
Set the List Separator to the semi-colon:
Then, in Excel SaveAs CSV
I would take a different approach.
In a Macro enabled Excel workbook:
1) Create a routine which will import a semi-colon-delimited file. It should take a filename as a parameter and return a workbook.
2) Create a routine which will export a workbook as a CSV. It should take a workbook as a parameter, a file name as a parameter, and export/close the workbook
3) Create a routine which reads a file list from the directory and then runs 1) and 2) on each file.
Additionally, I would not name the semi-colon delimited files CSV if you have any control over the original file names. By definition, CSV means Comma Separated Values. Name them something else. Then your routine only has to find the semi-colon files and can skip the CSVs because those have already been converted to comma separated.

How to append strings to other strings in a data set?

I want to append several strings in a data set with custom strings.
Example
Content of Dataset:
Test1
Test2
Test3
Result after appending:
Test1.com
Test2.com
Test3.com
Would I have to use regex to parse to the end of each Test[n] to be able to append it with a custom string (.com)? Has anyone got an example that describes exactly how to do it?
I am reading from a SQL-Table and writing values into a DataSet which is exported to CSV the following way:
$DataSet.Tables[0] | ConvertTO-Csv -Delimiter ',' -NotypeInformation |`% { $_ -replace '"','' } | out-file $outfile -Encoding "unicode"
The DataSet contains of Strings such as:
Banana01
Banana02
Apple01
Cherry01
Cherry02
Cherry03
The thing I want to do is append .com to only Cherry01, Cherry02, and Cherry03, and after appending .com, export it as a CSV file.
There are many ways. Here are a few:
# Using string concatenation
'Test1','Test2','Test3' | Foreach-Object{ $_ + '.com' }
# Using string expansion
'Test1','Test2','Test3' | Foreach-Object{ "$_.com" }
# Using string format
'Test1','Test2','Test3' | Foreach-Object{ "{0}{1}" -f $_,'.com' }
You could use something like this:
Example 1
$t = "test"
$t = $t + ".com"
Example 2
$test = #("test1","test2")
$test | ForEach-Object {
$t = $_ + ".com"
Write-Host $t}
With your added code I did this. I don't have a database to test it on, so I made the data set manually, so you might just have to change the $DataSet[0] in my code to $DataSet.Tables[0].
$DataSet[0] | ConvertTO-Csv -Delimiter ',' -NotypeInformation | Foreach-Object{$T=$_
IF($T -match "(Cherry\d\d)"){$T = $T -replace "(Cherry\d\d)(.+)",'$1.com$2'};$T } | out-file $outfile -Encoding "unicode"
$array | %{if($_ -match "^Cherry\d\d"){$_ += ".com"};$_}

Resources