Skip to content

Instantly share code, notes, and snippets.

@LarryWeiss
Created May 7, 2019 14:47
Show Gist options
  • Save LarryWeiss/349c646e9a2d088f19a5eeecfcf86b3a to your computer and use it in GitHub Desktop.
Save LarryWeiss/349c646e9a2d088f19a5eeecfcf86b3a to your computer and use it in GitHub Desktop.
ConvertFrom-CsvToFixedWidth function written in PowerShell
################################################################
#
# .SYNOPSIS
#
# PowerShell function named "ConvertFrom-CsvToFixedWidth"
#
# _____ _ ______
# / ____| | | | ____|
# | | ___ _ ____ _____ _ __| |_| |__ _ __ ___ _ __ ___
# | | / _ \| _ \ \ / / _ \ __| __| __| __/ _ \| _ _ \
# | |___| (_) | | | \ V / __/ | | |_| | | | | (_) | | | | | |
# \_____\___/|_| |_|\_/ \___|_| \__|_| |_| \___/|_| |_| |_|
#
# _____ _______ ______ _ ___ ___ _ _ _
# / ____| |__ __| | ____(_) | \ \ / (_) | | | | |
# _____| | _____ _| | ___ | |__ ___ _____ __| |\ \ /\ / / _ __| | |_| |__
# |_____| | / __\ \ / / |/ _ \| __| | \ \/ / _ \/ _ | \ \/ \/ / | |/ _ | __| _ \
# | |____\__ \\ V /| | (_) | | | |> < __/ (_| | \ /\ / | | (_| | |_| | | |
# \_____|___/ \_/ |_|\___/|_| |_/_/\_\___|\__,_| \/ \/ |_|\__,_|\__|_| |_|
#
#
# .DESCRIPTION
#
# Converts a CSV file to a fixed length text file
# No data is lost as each column is sized to fit the maximum width data in that column
# The first line of the text file contains the headers for the columns if they exist in the CSV file
#
# .EXAMPLE
#
# ConvertFrom-CsvToFixedWidth csvfilename.csv >filename.txt
#
# .EXAMPLE
#
# ConvertFrom-CsvToFixedWidth csvfilename.csv ";" >filename.txt
#
# .PARAMETER CSVPath
#
# Path to the CSV file
#
# .PARAMETER delimiter
#
# Optional parameter to specify the field delimiter character (defaults to ",")
#
# .PARAMETER HasHeader
#
# Optional switch to declare if the CSV file has a header record
#
# .OUTPUTS
#
# a fixed width version of the CSV file with each field width adjusted to
# contain the widest column content without wrapping
#
# .NOTES
#
# This version by Larry Weiss ([email protected]) derived from a version by
# Dave Wyatt
# https://davewyatt.wordpress.com/
# http://social.technet.microsoft.com/Profile/david%20wyatt
# https://social.technet.microsoft.com/Forums/en-US/5056daac-3e12-4518-bf0b-99890d9aa178/normal-csv-file-to-a-fixed-recordsize-text-file?forum=winserverpowershell
#
# .LINK
#
# This function is included in the collection at
# http://sp.ntpcug.org/PowerShell/Shared%20Documents
# as file
# http://sp.ntpcug.org/PowerShell/Shared%20Documents/Larry_Weiss_ConvertFrom-CsvToFixedWidth_function.ps1.txt
#
################################################################
function ConvertFrom-CsvToFixedWidth {
param (
[string] $CSVPath,
[string] $delimiter = ",",
[switch] $HasHeader
)
####################################################################################
#
# All code below expects the CSV file to be well-formed.
# See RFC 4180 for details at http://tools.ietf.org/html/rfc4180
#
####################################################################################
####################################################################################
#
# check arguments
#
if ( ! (Test-Path $CSVPath) ) { return }
if ( $delimiter.length -ne 1 ) { return }
####################################################################################
#
# Compute the number of fields in each record
# It is OK if it is larger that actual # of fields because of delimiter embedded in quoted data
#
$FirstTwoRows = @(get-content $CSVPath -TotalCount 2)
$FirstRowOfActualData = $FirstTwoRows[0]
if ( $FirstRowOfActualData.StartsWith("#TYPE") ) {
$FirstRowOfActualData = $FirstTwoRows[1]
$HasHeader = $true
}
$nFields = ($FirstRowOfActualData -split $delimiter).count
####################################################################################
#
# make a header array for the CSV file import using consecutive integers
# starting with "10001" as column headers
#
$header = @(); 1..$nFields | % { $header += (10000 + $_).ToString() }
####################################################################################
#
# import the CSV file with our artificial header and generate the fixed width text output
#
$width = 0
$looping = $true
while ( $looping ) {
$width += 1000
if ( $HasHeader ) {
####################################################################################
#
# formatting fixed length records including header
#
$fixed =
import-CSV -Path $CSVPath -delimiter $delimiter -header $header |
format-table * -autosize -wrap:$false |
out-string -stream -width $width
$looping = $fixed[0].length -ge $width
if ( ! $looping ) {
$fixed = $fixed[3],$fixed[2],$fixed[4..($fixed.count - 1)]
}
#
####################################################################################
}
else {
####################################################################################
#
# formatting fixed length records assuming no header
#
$fixed =
import-CSV -Path $CSVPath -delimiter $delimiter -header $header |
format-table * -autosize -wrap:$false |
out-string -stream -width $width |
select-object -skip 3
$looping = $fixed[0].length -ge $width
#
####################################################################################
}
}
$fixed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment