Need to split up a large patterned text file into multiple text files.

Hello,

I have a 5200 line text file full of DNS zone information.  It is formatted such with line 1 being the SOA record, and the last 2 lines of the zone are "Success..." and then "----" and then it repeats with the next zone.  An example of the top 2 records looks like the following:

domain1.com. SOA dauth5.server.com. contact.domain1.com. 2018020603 10800 3600 604800 10800
webmail.domain1.com. CNAME  domain1.com.
domain1.com. NS  dauth5.server.com.
domain1.com. MX 10 mail3.serverhosting.com.
domain1.com. A  255.255.138.2
mail.domain1.com. CNAME  mail3.serverhosting.com.
pop.domain1.com. CNAME  pop.serverhosting.com.
domain1.com. MX 10 mx1-us1.ppe-hosted.com.
www.domain1.com. CNAME  domain1.com.
domain1.com. NS  dauth6.server.com.
domain1.com. MX 20 mx2-us1.ppe-hosted.com.
smtp.domain1.com. CNAME  smtp.serverhosting.com.
SUCCESS: Getting information for Domain 'domain1.com' complete.
---------------
domain2.com. SOA dauth5.server.com. admin.server.com. 2018052503 900 600 86400 10800
domain2.com. A  192.168.255.2
domain2.com. MX 20 mx2-us1.ppe-hosted.com.
domain2.com. MX 10 mx1-us1.ppe-hosted.com.
www.domain2.com. CNAME  domain2.com.
mail.domain2.com. CNAME  mail4.serverhosting.com.
domain2.com. NS  dauth5.server.com.
domain2.com. NS  dauth6.server.com.
SUCCESS: Getting information for Domain 'domain2.com' complete.
---------------

Open in new window


I would like a powershell script that will take my file as in input, then split the file into multiple text files saved to a specific path.  The file name should be the very first word on line1 (domain1.com.text and domain2.com.text in the scenario above), then they should contain all lines up to the "Success:, and the following------" lines.  Those can be discarded.  So after processing the script given the text file above, I would be left with the following:

c:\temp\domain1.com.txt which would look like:
domain1.com. SOA dauth5.server.com. contact.domain1.com. 2018020603 10800 3600 604800 10800
webmail.domain1.com. CNAME  domain1.com.
domain1.com. NS  dauth5.server.com.
domain1.com. MX 10 mail3.serverhosting.com.
domain1.com. A  255.255.138.2
mail.domain1.com. CNAME  mail3.serverhosting.com.
pop.domain1.com. CNAME  pop.serverhosting.com.
domain1.com. MX 10 mx1-us1.ppe-hosted.com.
www.domain1.com. CNAME  domain1.com.
domain1.com. NS  dauth6.server.com.
domain1.com. MX 20 mx2-us1.ppe-hosted.com.
smtp.domain1.com. CNAME  smtp.serverhosting.com.

Open in new window


and c:\temp\domain2.com.text which would look like:
domain2.com. SOA dauth5.server.com. admin.server.com. 2018052503 900 600 86400 10800
domain2.com. A  192.168.255.2
domain2.com. MX 20 mx2-us1.ppe-hosted.com.
domain2.com. MX 10 mx1-us1.ppe-hosted.com.
www.domain2.com. CNAME  domain2.com.
mail.domain2.com. CNAME  mail4.serverhosting.com.
domain2.com. NS  dauth5.server.com.
domain2.com. NS  dauth6.server.com.

Open in new window


I think I will end up with a few hundred text files, but this would save me a ton of time!  Thanks in advance!
Chad KillionAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bill PrewIT / Software Engineering ConsultantCommented:
Here's a straight forward approach with PS.  I'm sure a shorter more cryptic version could be fashioned, but this seems to get the job done here.   Adjust the paths near the top and give it a try.

$InFile = "B:\EE\EE29138324\in.txt"
$DestDir = "B:\EE\EE29138324"
$Data = Get-Content $InFile
$OutFile = ""
foreach($Line in $Data)
{
    if($Line.SubString(0,8) -eq "SUCCESS:" -or $Line -eq "---------------"){
        $OutFile = ""
    } else {
        if($OutFile -eq "") {
            $OutFile = $Line.Split()[0].TrimEnd('.')
        }
        $Line >> "$DestDir\$OutFile.txt"
    }
}

Open in new window


»bp

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Brent ChallisPrincipal: ITCommented:
I prefer to code functions to make the utility more flexible and straightforward to move to a module. I have assumed that the line before the -------- separator is always SUCCESS, is it sometimes FAILURE?
function ConvertTo-SplitDNSZoneInfoFile
{
    [CmdletBinding()]
    Param
    (
        [String]$InputFilePath = "D:\DNSZoneInfo\DNSZoneInfo.txt",
        [String]$OutFileDirectory = "D:\DNSZoneInfo"
    )

    if ((Test-Path $InputFilePath) -and (Test-Path $OutFileDirectory))
    {
        $InputFile = Get-Content $InputFilePath
        $OutFileName = ""
        foreach ($line in $InputFile)
        {
            if ([String]::IsNullOrEmpty($OutFileName))
            {
                if ($line -notlike "--*")
                {
                    $OutFileName = $line.Split(" ")[0] + "txt"
                    $OutFilePath = Join-Path -Path $OutFileDirectory -ChildPath $OutFileName
                }
            }
            else
            {
                if ($line -like "SUCCESS*" -or $line -Like "--*")
                {
                    $OutFileName = ""
                }
                else
                {
                    $line | Out-File $OutFilePath -Append
                }
            }
        }
    }
    else
    {
        Write-Warning "Unable to find either $InputFilePath or $OutFileDirectory"
    }
}

ConvertTo-SplitDNSZoneInfoFile

Open in new window

Chad KillionAuthor Commented:
Bill - Using your method, the top line of the resulting text files is missing...example:

domain1.com. SOA dauth5.server.com. contact.domain1.com. 2018020603 10800 3600 604800 10800

Doesn't appear in the resulting file on any of the files created.  The first line should always be the SOA line.

Brent - Using your method, the SOA line does appear, but not in order...its like the order gets mixed up and the SOA line appears on line 5 or 6 but not line 1 each time as it should?
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Bill PrewIT / Software Engineering ConsultantCommented:
I tested with what you posted and it worked fine here, my test files attached.  If you want to post your actual input file I can test here, it may be that that first line has some extra special characters that are causing a problem...

in.txt
domain1.com.txt
domain2.com.txt


»bp
Chad KillionAuthor Commented:
I took your in file and and appended 2 real records to it and I have the same results, very odd...no SOA line at the top of any of the resullting file...
dom_dns.txt
1talltrees.com.txt
456jobs.com.txt
domain1.com.txt
domain2.com.txt
Bill PrewIT / Software Engineering ConsultantCommented:
I took your dom_dns.txt file, ran it through the script I posted here, and the 4 result files have the first line here.

What version of powershell do you have?

And did you make any changes to the script I posted?


»bp
Chad KillionAuthor Commented:
Can't explain it...but it is working now.  I just re-copied the script and changed lines 1 and 2 and re-ran the script and SOA shows up as line #1 now.  Sorry for wasting your last 30 minutes!  Thanks so much for the help!
Bill PrewIT / Software Engineering ConsultantCommented:
No worries, glad it's working there now.


»bp
Brent ChallisPrincipal: ITCommented:
I checked my code and it consumed the first line when changing the output file name rather than outputting it.  I have also added a switch to indicate that you want to delete the output file if it exists.
function ConvertTo-SplitDNSZoneInfoFile
{
    [CmdletBinding()]
    Param
    (
        [String]$InputFilePath = "D:\DNSZoneInfo\DNSZoneInfo.txt",
        [String]$OutFileDirectory = "D:\DNSZoneInfo",
        [Switch]$Clobber
    )

    if ((Test-Path $InputFilePath) -and (Test-Path $OutFileDirectory))
    {
        $InputFile = Get-Content $InputFilePath
        $OutFileName = ""
        foreach ($line in $InputFile)
        {
            if ([String]::IsNullOrEmpty($OutFileName))
            {
                if ($line -notlike "--*")
                {
                    $OutFileName = $line.Split(" ")[0] + "txt"
                    $OutFilePath = Join-Path -Path $OutFileDirectory -ChildPath $OutFileName
                    if ($Clobber -and (Test-Path $OutFilePath))
                    {
                        Remove-Item $OutFilePath
                    }
                }
            }
            if ($line -like "SUCCESS*" -or $line -Like "--*")
            {
                $OutFileName = ""
            }
            else
            {
                $line | Out-File $OutFilePath -Append
            }
        }
    }
    else
    {
        Write-Warning "Unable to find either $InputFilePath or $OutFileDirectory"
    }
}

ConvertTo-SplitDNSZoneInfoFile -Clobber

Open in new window

Chad KillionAuthor Commented:
Thanks again, and Brent the second one worked out great as well!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.