function Import-Cut{ [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias('FullName','Name')] [String[]]$Path, [Parameter(ParameterSetName="OpModeByte")] [Alias("Characters")] [Alias("c")] [Alias("b")] [string]$Bytes, [Parameter(ParameterSetName="OpModeField")] [Alias("f")] [string]$Fields, [Parameter(ParameterSetName="OpModeField")] [Alias("d")] [String]$Delimiter="`t", [Parameter(ParameterSetName="OpModeField")] [Alias("s")] [switch]$OnlyDelimited=$false, [Parameter()] [switch]$Complement=$false, [Parameter()] [Bool]$Truncate=$false, # If '$true' will not add bytes/fields beyond the end of the record # If "$false" a fixed number of bytes/fields will be cut, even when string is short # This can present a problem if there's a field range pair that ends with a hyphen (-) # and the 'Fields' option is being used because it isn't possible to know how may # fields may be discovered on each line of the input. In this case only as many fields # will be returned as there are fields in the record [Parameter()] [Alias("z")] [switch]$ZeroTerminated # NOT USED: Line delimeter is NUL (0x00), not CrLf ) ################################################################################## # Begin code ################################################################################## begin { enum OperatingModes{ UndefinedMode ByteMode # Output characters that are in the given byteranges. FieldMode # Output the given delimiter-separated fields. } enum FieldStringOptions { SETFLD_ALLOW_DASH = 0x01 # Allow single dash meaning 'all fields' SETFLD_COMPLEMENT = 0x02 # Complement the field list SETFLD_ERRMSG_USE_POS = 0x04 # When reporting errors, say 'position' instead # of 'field' (used with cut -b/-c) } # By default, all non-delimited lines are printed. $SuppressNonDelimited = $false if ($OnlyDelimited) { $SuppressNonDelimited = $true } # Will the code deal with bytes\characters or delimited fields in the input file? [uint16]$OperatingMode = [OperatingModes]::UndefinedMode if ($Bytes.Length -gt 0) { $OperatingMode = [uint32][OperatingModes]::ByteMode } elseif ($Fields.Length -gt 0){ $OperatingMode = [uint32][OperatingModes]::FieldMode } else{ Throw [ArgumentException]("Either '-Bytes', '-Characters', or '-Fields' must be specified") } [uint32]$Options = 0 # Should exceptions use 'Position' instead of 'Field' when reporting errors in the set of field ranges? if ($OperatingMode -eq [int][OperatingModes]::ByteMode){ $Options = $Options -bor [uint32][FieldStringOptions]::SETFLD_ERRMSG_USE_POS } # Are the field range pairs to be invereted? if ($complement){ $Options = $Options -bor [uint32][FieldStringOptions]::SETFLD_COMPLEMENT } $SpecListString = "" If ($OperatingMode -band [uint32][OperatingModes]::ByteMode){ $SpecListString = $Bytes } Elseif ($OperatingMode -band [uint32][OperatingModes]::FieldMode){ $SpecListString = $Fields } [System.Collections.ArrayList]$Frp = @() # a list of field/position pairs $Frp = @(SetFields -SpecListString $SpecListString -Options $Options) } process { $Path | ForEach-Object { Get-Content -Path $_ | Foreach-Object{ if ($OperatingMode -eq [uint16][OperatingModes]::ByteMode){ CutBytes -Frp $Frp -InputString $_ -Trunc $Truncate| Write-Output } else{ CutFields -Frp $Frp -InputString $_ -Delimiter $Delimiter -Trunc $Truncate -SuppressNonDelimited $SuppressNonDelimited | Write-Output } } } } end { # currently there's no need for any cleanup } }