PowerShell to Split multiple text file in the folder to an output folder according 10000 lines with Added Text Each Files - powershell

#Path // CHANGE FILE NAME AND RUN = 'C:\BassBeta\3.sql'
#$SQLFilePath = 'C:\Users\paul.ang\Desktop\UOS\UOS_Discovery\rev\test\*.*'
Get-ChildItem C:\TEST -include *.sql -rec | ForEach-Object {gc $_; ""} | out-file C:\test\test.txt
#CHECKING IF >5000 LINES
$fileContent = Get-Content $SQLFilePath
$Lines = (Get-content $SQLFilePath | Measure-Object –Line).Lines
#$lineNumber = $Lines
IF ($Lines -ge 5000)
{
#Header /OK
$headertxt = 'BEGIN TRAN'
$($headertxt; Get-Content $SQLFilePath) | Set-Content $SQLFilePath
#Body /OK
$textToAdd_B = '
COMMIT TRAN
--ROLLBACK
BEGIN TRAN'
$lineNumber_B = '5002'
$fileContent = Get-Content $SQLFilePath
$fileContent[$lineNumber_B-1] += $textToAdd_B
$fileContent | Set-Content $SQLFilePath
#Footer /OK
$textToAdd_F = '
COMMIT TRAN
--ROLLBACK'
$fileContent = Get-Content $SQLFilePath
$Lines = (Get-content $SQLFilePath | Measure-Object –Line).Lines
$lineNumber_F = $Lines
$fileContent[$lineNumber_F] += $textToAdd_F
$fileContent | Set-Content $SQLFilePath
}
ELSEIF ($Lines -le 5000)
{
#Header /OK
$headertxt = 'BEGIN TRAN'
$($headertxt; Get-Content $SQLFilePath) | Set-Content $SQLFilePath
#Footer /OK
$textToAdd_F = '
COMMIT TRAN
--ROLLBACK'
$fileContent = Get-Content $SQLFilePath
$Lines = (Get-content $SQLFilePath | Measure-Object –Line).Lines
$lineNumber_F = $Lines
$fileContent[$lineNumber_F-1] += $textToAdd_F
$fileContent | Set-Content $SQLFilePath
}
'Hi all experts, First of all I would like to say thank you and sorry if there is duplicated post in there as I not really active in Stack flow. Recently, My company assigned me a task to split sql files and deliver to production team. I hope any expert here can guide me there My requirement as below:- I would like to split multiple text files in the input folder according my setting 10000 lines each text file and after split 10000 lines each file add text 'BEGIN TRAN' to the text file then save it in the output folder. Since this task is very high frequency and previously I run it manually with stress =.=". Somehow I copy source from the internet and hope can mix and match to make it work. I'm no expert to PowerShell but would like to enhance my work and make my work life balance. TQ'

I test following code after creating a test file with this code which puts sequential number in a file
$writer = [System.IO.StreamWriter]::new("c:\temp\test\bigFile.sql")
for($i = 0; $i -lt 1000000; $i++)
{
$writer.WriteLine($i)
}
$writer.Flush()
$writer.Close()
Than used following to split the large file
#Path // CHANGE FILE NAME AND RUN = 'C:\BassBeta\3.sql'
#$SQLFilePath = 'C:\Users\paul.ang\Desktop\UOS\UOS_Discovery\rev\test\*.*'
$basefolder = "c:\temp\test"
$headertxt = 'BEGIN TRAN'
$fileSize = 5000
$files = Get-ChildItem $basefolder -include *.sql -rec
foreach($file in $files)
{
$reader = [System.IO.StreamReader]::new($file.fullname)
$lines = [System.Collections.ArrayList]::new()
Write-Host "Start Read = " $file.FullName
while(($line = $reader.ReadLine()) -ne $null)
{
$lines.Add($line) | Out-Null;
}
Write-Host "End Read = " $file.FullName
if($lines.Count -ge $fileSize)
{
#remove sql from filename
$lastIndex = $file.fullname.LastIndexOf('.')
$folder = $file.fullname.substring(0, $lastIndex)
Write-Host "folder name = " $folder
if(!(Test-Path $folder))
{
Write-Host "create new folder = " $folder
New-Item $folder -ItemType Directory
$fileCount = 0
for($i = 0; $i -lt $lines.Count; $i += $fileSize)
{
++$fileCount
$newFilename = $folder + "\" + $fileCount + ".sql"
Write-Host "new Filename = " $newFilename
$writer = [System.IO.StreamWriter]::new($newFilename)
$writer.Writeline($headertxt)
for($j = $i; ($j -lt $lines.Count) -and ($j -lt ($i + $fileSize)); $j++)
{
$writer.WriteLine($lines[$j])
}
$writer.Flush()
$writer.Close()
}
}
else
{
Write-Host "Folder Exists" $folder
}
}
}

Related

how to split a csv file into small chunks with headers using powershell

I am using the following code to split the large csv file into chunks. But the headers are not appending output files.
Here is the powershell script:
$InputFilename = Get-Content 'C:\Users\Sridhar\Downloads\Leads.csv'
$destinationPath = 'C:\Users\Sridhar\Downloads\'
$OutputfilenamePattern = 'leads_'
$LineLimit = 500
$line = 0
$i = 0
$file = 0
$start = 0
$header = $InputFilename[0]
while ($line -le $InputFilename.Length){
if($i -eq $LineLimit -Or $line -eq $Inputfilename.Length){
$file++
$Filename = "$destinationPath$OutputfilenamePattern$file.csv"
$InputFilename[$start..($line-1)] | Out-file $Filename -Force -Encoding utf8
$start =$line;
$i = 0
Write-Host "$Filename"
}
$i++
$line++
}
For a complete explanation, see: Mastering the (steppable) pipeline
$BatchSize = 500
Import-Csv .\Leads.csv |
ForEach-Object -Begin {
$Index = 0
} -Process {
if ($Index % $BatchSize -eq 0) {
$BatchNr = [math]::Floor($Index++/$BatchSize)
$Pipeline = { Export-Csv -notype -Path .\leads_$BatchNr.csv }.GetSteppablePipeline()
$Pipeline.Begin($True)
}
$Pipeline.Process($_)
if ($Index++ % $BatchSize -eq 0) { $Pipeline.End() }
} -End {
$Pipeline.End()
}

How to modify Firefox config (pref.js) line using Powershell

Modifying the Mozilla Firefox Pref.js file using PowerShell.
Need to modify the pref.js file line to reflect a new value
(Hence, instead of any value under user_pref("network.automatic-ntlm-auth.trusted-uris", "*"); to show user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com") or just add changes after the *
$TopDir = "$env:APPDATA\Mozilla\Firefox\Profiles"
$FileName = 'prefs.js'
$DefaultProfileDir = (Get-ChildItem -LiteralPath $TopDir -Directory).
Where({
$_.FullName -match '\.default'
}).FullName
$FullFileName = Join-Path -Path $DefaultProfileDir -ChildPath $FileName
$data = foreach($line in Get-Content $FullFileName)
{
if($line -contains 'user_pref("network.automatic-ntlm-auth.trusted-uris".*')
{
$line -replace '*' , 'user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com");'
}
else
{
$line
}
}
$data | Set-Content C:\testfolder\test2.txt
Nelson,
I didn't have your line in my FF profile but I got the code to work on another line so you should be able to modify it to work with yours.
$TopDir = "G:\Test"
$FileName = 'prefs.js'
$FullFileName = "$TopDir\$FileName"
Clear-Host
$Data = foreach($line in Get-Content $FullFileName) {
if( ($line.IndexOf('browser.bookmarks.restore_default_bookmarks')) -ne -1)
{
If ($line.IndexOf('false') -ne -1) {
$line = $line.replace( 'false' , 'true')
}
}
$line
}
$data | Set-Content $("$TopDir" + "\prefs2.js")
I think your code would be:
$TopDir = "$env:APPDATA\Mozilla\Firefox\Profiles"
$FileName = 'prefs.js'
$DefaultProfileDir = (Get-ChildItem -LiteralPath $TopDir -Directory).
Where({
$_.FullName -match '\.default'
}).FullName
$FullFileName = Join-Path -Path $DefaultProfileDir -ChildPath $FileName
$Data = foreach($line in Get-Content $FullFileName) {
if( ($line.IndexOf('network.automatic-ntlm-auth.trusted-uris')) -ne -1)
{
If ($line.IndexOf('*') -ne -1) {
$line = $line.replace( '*' , 'abc.com,.abcd.com,.abcde.com')
}
}
$line
}
$data | Set-Content C:\testfolder\test2.txt
Note: -contains is designed for lists.
HTH
I extended it to be easier to use any property
Input
user_pref("foo", "bar")
user_pref("network.automatic-ntlm-auth.trusted-uris", "*")
Output
user_pref("foo", "bar")
user_pref("network.automatic-ntlm-auth.trusted-uris", ".abc.com,.abcd.com,.abcde.com")
$lines = 'user_pref("foo", "bar")', 'user_pref("network.automatic-ntlm-auth.trusted-uris", "*")'
# multi-line regex for readability
$regex = '(?x)
(?<prefix>user_pref\()
(?<name>
".*"
)
\s*,\s*
(?<value>
".*"
)
(?<suffix>.*)
'
"`ninput:"
$lines
"`noutput:"
$lines | ForEach-Object {
if($_ -match $regex) {
if($matches.name -eq '"network.automatic-ntlm-auth.trusted-uris"') {
$_ = '{0}{1}, {2}{3}' -f #(
$Matches.prefix,
$Matches.name,
'".abc.com,.abcd.com,.abcde.com"',
$Matches.suffix
)
}
}
$_
}

loop for txt split file

I am trying to make this following query loop through and split all the text files in the current directory. I currently have two different files named TestingInfo[1] & TestingInfo[2].
Directory where files are located: \\C\users$\Pepe\Desktop\TestInfoFolder
The files look like this:
TestingInfo[1]:
[IMPORT]
1
2
3
[IMPORT]
4
5
6
TestingInfo[2]:
[IMPORT]
7
8
9
10
Code I have so far:
$Path = "\\C\users$\Pepe\Desktop\TestInfoFolder"
$InputFile = (Join-Path $Path "TestingInfo[1].txt")
$Reader = New-Object System.IO.StreamReader($InputFile)
$N = 1
While (($Line = $Reader.ReadLine()) -ne $null) {
if ($Line -match "[IMPORT]") {
$OutputFile = $matches[0] + $N + ".txt"
$N++
}
Add-Content (Join-Path $Path $OutputFile) $Line
}
Your sort of doing it the hard way, calling the .NET libraries directly.
This approach should be about right, and much more simple / in line with PowerShell.
$curFileContents
$i = 0
Get-ChildItem "pathOfFiles\" | {
Get-Content $_ | ForEach-Object {
$line = $_.Split(" ")
foreach ($word in $line)
{
if ($word -match "[INPUT]")
{
$i++
}
else
{
$curFileContents += $word + " "
}
}
$curFileContents | Out-File -FilePath "PathToFile\output$i.txt"
}
}
Which gives text files where the content looks like:
1 2 3
Reusing your code, and adding in the get-child item would look like:
$Path = "\\C\users$\Pepe\Desktop\TestInfoFolder"
Get-ChildItem $Path | foreach-object {
$InputFile = $_.FullName
$Reader = New-Object System.IO.StreamReader($InputFile)
$N = 1
While (($Line = $Reader.ReadLine()) -ne $null) {
if ($Line -match "[IMPORT]") {
$OutputFile = $matches[0] + $N + ".txt"
$N++
}
Add-Content (Join-Path $Path $OutputFile) $Line
}
}

I want to be able to split the output of a directory and its subdirectory

I want to be able to split the output of a directory and its sub directory with PowerShell. Currently this is my code:
Get-Childitem -path \\serverName\lettertext\Customer -Recurse -Include *.txt |
Out-file c:\Letters\output.txt
This lists all the text content of the directory and subfolder.
The full directory format is:
\\serverName\lettertext\Customer\Client Group\Client\Client Division
For this reseaon I want to out the result in this format:
Customer| CLient Group| CLient| CLient Division| Outputs.txt
Does anyone know how I can achieve that?
I changed the code, this is what I changed it to but its not working:
# Trying to pull a directory listing of customized letter text files
$Testing = $false
$DisplayElapsedTime = 0
[DateTime] $StartDate = Get-Date
$RootPath = "\\servername\LetterText"
$pattern = "*.txt"
$Customer = ""
#$FileName = 'C:\letters\' + $FileName
if ($Testing -eq $false) {
$x = Read-Host 'Customer Name'
if ($x -ne $null) {$Customer = $x}
$x = $null
$x = Read-Host 'File Name (blank for all) '
if ($x -ne "") {$pattern = $x}
} else {
}
if ($Customer -eq "") {
$RequestedCustomer = " All"
$FileName = 'LetterTextFiles ' + $StartDate.Year.ToString() +
$StartDate.Month.ToString('00') +
$StartDate.Day.ToString('00') + '.ltr'
} else {
$RequestedCustomer = $Customer
$FileName = 'LetterTextFiles ' + $StartDate.Year.ToString() +
$StartDate.Month.ToString('00') +
$StartDate.Day.ToString('00') + '--' + $Customer + '.ltr'
}
#$FileName = 'C:\util\' + $FileName
Write-Host '' | Out-File -FilePath $FileName -Encoding Default
"Requested Customer: "+ $RequestedCustomer >> $FileName
"Requested Files: " + $pattern >> $FileName
$Path = $RootPath + '\' +$Customer
cls
try {
$Results = Get-ChildItem $Path -Recurse -Include:$pattern
if ($DisplayElapsedTime -eq -1) {
[DateTime] $StartTime
#'Listing Time:'
$StartTime = Get-Date
}
$DirectoryName = ''
foreach ($result in $Results) {
if ($DirectoryName -ne $result.Directory.Name) {
#" " >> $FileName
$y = ""
$DirectoryName = $result.Directory.Name
$FullName = $result.FullName.Replace($RootPath,'').Split('\')
$level = $result.FullName.Replace($RootPath,'').Split('\')
if ($result.DirectoryName -eq $RootPath) {
$y = 'COBRAPoint base letters:'
#Write-Host $y | Out-File -FilePath $FileName -Encoding Default
" " >> $FileName
$y >> $FileName
} else {
for ($x = 0; $x -lt $level.Length -1; $x++) {
switch ($x) {
1 {$y = 'Customer: '+ $level[$x]}
2 {$y = ' Client Group: '+ $level[$x]}
3 {$y = ' Client: '+ $level[$x]}
4 {$y = ' Client Division: '+ $level[$x]}
}
#Write-Host $y|out-file -FilePath $FileName -Encoding Default
$y >> $FileName
}
}
}
$y = "`t" + $result.Name
#Write-Host $y | Out-File -FilePath $FileName -Encoding Default
$y >> $FileName
#break
}
} catch [System.Exception] {
$y = "No Files Found"
$y >> $FileName
}
#Out-File $FileName
#$Output > 'out.txt'
$FileName
'Done'
if ($DisplayElapsedTime -eq -1) {
'Total Time:'
New-TimeSpan -Start $StartTime -End (Get-Date)
}
One option:
Get-Childitem -path \\serverName\lettertext\Customer -Recurse -Include *.txt |
ForEach-Object {
$Parts = $_.fullname.split('\')[4..7]
[PSCustomObject]#{
Customer = $Parts[0]
ClientGroup = $Parts[1]
Client = $Parts[2]
ClientDivision = $Parts[3]
FileName = $_.FullName | Split-Path -Leaf
}
} | Export-Csv c:\somedir\clientfile.csv -NoTypeInformation
try this
$folder = 'c:\temp'
$customer = Split-Path $folder -Leaf
Get-Childitem -Path $folder -Recurse -Include *.txt | % {
$sub = ($_.fullname -replace [regex]::Escape($folder)).trim('\')
$split = $sub.split('\')
if ($split.count -eq 4) {
[pscustomobject]#{
Customer = $customer
ClientGroup = $split[0]
Client = $split[1]
ClientDivision = $split[2]
File = $split[3]
}
}
} | epcsv c:\Letters\output.csv -not

Add Content in Powershell

I need to search through multiple files and underneath specific lines i need to insert lines referenced previously in each respective file. So far i cannot get my script to work at all.
This is what i have so far :
$TextLocation = "M:\test"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pagetitle = "DS_PGSEQ-DC:"
$a = Get-Content $file.FullName | Select-String "AssignedToUserID-TZ"
$b = Get-Content $file.FullName | Select-String "EFormID-TZ"
Foreach ($line in $file)
{
if([String]$line -eq "DS_PGSEQ-DC:0001")
{
}
elseif([String]$line -eq $pagetitle)
{
Add-Content $file.FullName ($a -and $b)
}
}
}
There are two common ways for inserting text into a text file:
Process the input file(s) line-by-line, write the output to a temporary file and replace the input file(s) with them temp file afterwards.
for ($file in $files) {
$filename = $file.FullName
Get-Content $filename | % {
if ( $_ -match 'seach pattern' ) {
$_
"new line"
}
} | Out-File $tempfile
MoveItem $tempfile $filename -Force
}
Read the entire content of the file(s), insert the text by using a regular expression replacement, and write the modified content back to the file(s).
for ($file in $files) {
$text = [System.IO.File]::ReadAllText($file.FullName)
$text -replace '.*search pattern.*', "`$0`nnew line" |
Out-File $file.FullName
}
$TextLocation = "M:\test"
$Outputlocation = "M:\test\output"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pattern = "\d\d\d[2-9]"
$found=$false
$contains=$false
$lines = Get-Content($file.FullName) |
Foreach-object {
if ($_ -match "AssignedToUserID-TZ") {
$a = $_
}
if ($_ -match "EFormID-TZ") {
$b = $_
}
if ($_ -match "DS_PGSEQ-DC:$pattern") {
if($found -eq $false) {
$found=$true
}
} else {
$found=$false
}
if ($found -eq $true) {
$contains=$true
#Add Lines after the selected pattern
$_
$a
$b
}
if ($found -ne $true) {
$_
}
} | Set-Content($Outputlocation + "\" + $file.Name)
}