Mehfuz Hossain
Learning never stops....

Make File Merge easy with Powershell

Friday, April 13, 2007 11:29 PM

Powershell, is a great tool for handy scripting. It is often needed that you need to write sql scripts in isolated files. The is good in terms of finding errors in script, and focusing on one part while developing part of the sytem.But , as the number of script files grows big , the deployment issue becomes a headache for the release manager to handle your scripts.

I used to think that the best solution, for merging files, is to use dos copy /xcopy commend, but this often gets screwed up for really big scripts having evernt large srings within.

Though .Net has rich libray for that,it not aways easy to make a console app which i can share with my collegues, therefore i started tiny a powershell that made my life more easier.

The goal of my power shell, i will give source dirercoty , exetenstion(filetype to be included in merge) and optionally a diliminator(for ex. i want to have "GO" keyword at end of each sql file).


Logic:

Get all files for provided extenstion
Read the whole content, and append it in a string builder
Add the diliminator
Finally Combine them to one file.


Code

Param ($source="c:\Test", $extenstion ="*.sql", $outputFile = "outputFile.sql" , $blockTerminator = "GO" )

[System.IO.DirectoryInfo]$directoryInfo = New-Object System.IO.DirectoryInfo($source);
$rgFiles = $directoryInfo.GetFiles($extenstion);

$builder = New-Object System.Text.StringBuilder;

foreach ($fileInfo in $rgFiles)
{
[System.IO.FileStream]$fReader = $fileInfo.OpenRead();

if (-not ($fileInfo -eq $null))
{

write $fileInfo.Name;
$reader = New-Object System.IO.StreamReader($fReader);
$builder.AppendLine($reader.ReadToEnd());
$builder.AppendLine($blockTerminator);
}
}

if (-NOT $source.EndsWith('\'))
{
 $source = $source + '\';
}

$outputFile = $source + $outputFile;

[System.IO.FileStream]$fWriter = New-Object System.IO.FileStream($outputFile, [System.IO.FileMode]::OpenOrCreate);
$writer = New-Object System.IO.StreamWriter($fWriter);

$writer.Write($builder.ToString());
$writer.Flush();
$writer.Close();


Terminology

Param - This excepts user input from shell, optionally you set default value
All the status methods in .net are called with double "::".
Classes are declared with fully quilifed name
New-Object : use for class declartion , optionally you can use -comObject to declare com objects.


How to use

Copy the code , paste it in a text file , rename it to .ps1 extenstion.
Get the exeution poiicy of your shell enviroment , by default it is Restricted , you can know that from calling Get-ExecutionPolicy command. In this mode you cant run scriptlets. Use Set-ExecutionPolicy RemoteSinged.
Run the script , do add the ".\" sign before your file name.


Example

PS C:\Users\mehfuz> .\FileMerge.ps1 basedirectory  extension mergedFile.sql blockdeliminator

Ex  ./Filemerger.ps1 c:\test *.sql mehfuz.sql GO

Enjoy!

 


Feedback

No comments posted yet.


Post a comment





 

Please add 3 and 1 and type the answer here: