<#
.SYNOPSIS
ソート & ユニーク
.PARAMETER mode
動作モード 0:ソート
1:ソート & ユニーク
2:ソート & ユニーク(重複数を出力)
3:ソート & ユニーク(重複していない行を出力。重複数も出力)
4:ソート & ユニーク(重複している行を出力。重複数も出力)
.PARAMETER index
ソート & ユニークする位置を指定する。
0:1 文字目から n 文字。(左端)
1:m 文字目以降。 (右端)
2:m 文字目から n 文字。(中央)
.PARAMETER SJIS
ソート & ユニークをキャラクタコード「シフト JIS」で行う。
省略時はユニコードで行う。
.EXAMPLE
Get-Context .\input.txt | uq
.EXAMPLE
Get-Context .\input.txt | uq -index 0,3
.EXAMPLE
Get-Context .\input.txt | uq -index 1,3
.EXAMPLE
Get-Context .\input.txt | uq -index 2,4,5
.INPUTS
標準入力。
.OUTPUTS
標準出力。
#>
Param
(
[Int32]
$mode = 1,
[Int32[]]
$index,
[Switch]
$SJIS
)
$context = @{}
if(
$SJIS )
{
$context.enc = [System.Text.Encoding]::Default
}
else
{
$context.enc = [System.Text.Encoding]::Unicode
}
# 0 … 1 文字目から n 文字。(左端)
# 1 … m 文字目以降。 (右端)
# 2 … m 文字目から n 文字。(中央)
if(
$index -ne
$Null )
{
switch(
$index[0] )
{
0
{
if(
$index.Count -lt 2 )
{
Write-Host '引数不足'
return 1
}
$context.nStart = 0
$context.nLength =
$index[1]
}
1
{
if(
$index.Count -lt 2 )
{
Write-Host '引数不足'
return 1
}
$context.nStart =
$index[1]
$context.nLength = [Int32]::MaxValue
}
2
{
if(
$index.Count -lt 3 )
{
Write-Host '引数不足'
return 1
}
$context.nStart =
$index[1]
$context.nLength =
$index[2]
}
default
{
Write-Host '引数 -index 異常'
return 1
}
}
}
else
{
$context.nStart = 0
$context.nLength = [Int32]::MaxValue
}
Function Extract-Line-Part( [String]
$line,
$context )
{
[Int32]
$nStart =
$context.nStart
[Int32]
$nLength =
$context.nLength
if(
$nStart -gt
$line.Length )
{
$nStart = 0
$nLength = 0
}
else
{
if( (
$nStart +
$nLength) -gt
$line.Length )
{
$nLength =
$line.Length -
$nStart
}
}
$line.Substring(
$nStart,
$nLength)
}
Function In-Binary-List( [System.Collections.Generic.List[Object]]
$ls )
{
Process
{
$linePart = Extract-Line-Part
$line $context
$i = @{}
$i.stream =
$context.enc.GetBytes(
$linePart )
$i.line =
$line
$i.count = 0
$ls.Add(
$i )
}
}
Function In-Text-List( [System.Collections.Generic.List[Object]]
$ls )
{
Process
{
$linePart = Extract-Line-Part
$line $context
$i = @{}
$i.stream =
$linePart
$i.line =
$line
$i.count = 0
$ls.Add(
$i )
}
}
Function Display-Factor
{
Process
{
$_.line
}
}
Function Display-FactorAll
{
Process
{
$_.line + "`t-->" + "`t" +
$_.count
}
}
Function Uniq-Filter
{
Process
{
if(
$_.count -ge 1 )
{
$_
}
}
}
Function Single-Filter
{
Process
{
if(
$_.count -eq 1 )
{
$_
}
}
}
Function Duplicate-Filter
{
Process
{
if(
$_.count -ge 2 )
{
$_
}
}
}
Function Compare-Binary( [Byte[]]
$l, [Byte[]]
$r )
{
[Int32]
$diff =
$l.Count -
$r.Count
if(
$diff -eq 0 )
{
if(
$l.Count -eq 0 )
{
return 0
}
$min =
$l.Count
}
else
{
if(
$l.Count -eq 0 )
{
return -1
}
if(
$r.Count -eq 0 )
{
return 1
}
if(
$diff -lt 0 )
{
$min =
$l.Count
}
else
{
$min =
$r.Count
}
}
for(
$i = 0;
$i -lt
$min;
$i ++ )
{
[Int32]
$nValueL =
$l[
$i]
[Int32]
$nValueR =
$r[
$i]
$n =
$nValueL -
$nValueR
if(
$n -ne 0 )
{
if(
$n -lt 0 )
{
return -1
}
else
{
return 1
}
}
}
if(
$diff -ne 0 )
{
if(
$diff -lt 0 )
{
return -1
}
else
{
return 1
}
}
return 0
}
Function Sort-Binary-List( [System.Collections.Generic.List[Object]]
$ls )
{
for(
$y = 0;
$y -lt
$ls.Count - 1;
$y ++ )
{
$itemY =
$ls[
$y]
for(
$x =
$y + 1;
$x -lt
$ls.Count;
$x ++ )
{
$itemX =
$ls[
$x]
$r = Compare-Binary
$itemY.stream
$itemX.stream
if(
$r -gt 0 )
{
$ls[
$y] =
$itemX
$ls[
$x] =
$itemY
$itemY =
$itemX
}
}
}
}
Function Sort-Text-List( [System.Collections.Generic.List[Object]]
$ls )
{
for(
$y = 0;
$y -lt
$ls.Count - 1;
$y ++ )
{
$itemY =
$ls[
$y]
for(
$x =
$y + 1;
$x -lt
$ls.Count;
$x ++ )
{
$itemX =
$ls[
$x]
$r = [System.String]::Compare(
$itemY.stream,
$itemX.stream )
if(
$r -gt 0 )
{
$ls[
$y] =
$itemX
$ls[
$x] =
$itemY
$itemY =
$itemX
}
}
}
}
Function Binary-Uniq-Count
{
Begin
{
$base =
$Null
}
Process
{
$line =
$_
if(
$base -eq
$Null )
{
$base =
$line
$base.count = 1
}
else
{
$r = Compare-Binary
$base.stream
$line.stream
if(
$r -ne 0 )
{
$base =
$line
$base.count = 1
}
else
{
$base.count ++;
}
}
}
}
Function Text-Uniq-Count
{
Begin
{
$base =
$Null
}
Process
{
$line =
$_
if(
$base -eq
$Null )
{
$base =
$line
$base.count = 1
}
else
{
if(
$base.stream.Equals(
$line.stream) -eq 0 )
{
$base =
$line
$base.count = 1
}
else
{
$base.count ++;
}
}
}
}
$list = [System.Collections.Generic.List[Object]]::new()
if(
$SJIS )
{
($(
$Input)) | In-Binary-List
$list
Sort-Binary-List
$list
}
else
{
($(
$Input)) | In-Text-List
$list
Sort-Text-List
$list
}
switch(
$mode )
{
0
{
# 0 … ソート
$list | Display-Factor
}
{
$_ -in 1,2,3}
{
# 1 … ユニーク
# 2 … ソート & ユニーク(重複数を出力)
# 3 … ソート & ユニーク(重複していないものを出力)
# 4 … ソート & ユニーク(重複しているものを出力)
if(
$SJIS )
{
$list | Binary-Uniq-Count
}
else
{
$list | Text-Uniq-Count
}
}
1
{
# 1 … ユニーク
$list | Uniq-Filter | Display-Factor
}
2
{
# 2 … ソート & ユニーク(重複数を出力)
$list | Uniq-Filter | Display-FactorAll
}
3
{
# 3 … ソート & ユニーク(重複していないものを出力)
$list | Single-Filter | Display-FactorAll
}
4
{
# 4 … ソート & ユニーク(重複しているものを出力)
$list | Duplicate-Filter | Display-FactorAll
}
}