汎用機メモっとくか

しごと用の(学習メモ&お気に入り保存)。

でっきるかな?PowerShell 005 PowerShellでfoldコマンド

2018年12月07日 01時47分56秒 | PowerShell

環境 Windows10 64bit PowerShell version 5.0 にて動かす機会があった。
性能のいいマシンならそこそこ動くと思われる。

 Windows7 32bit PowerShell version 2.0 の低スペックノートPCでは、

メモリを大量消費の上、速度もコード量の割に遅い

[foldで150バイト]

[byte[]]$crlf = @(13,10)
gc fixed150.txt -encoding byte -readcount 150  -totalcount (150*200) |%{$_ + $crlf} | sc out_Fixed150.txt -encoding byte


[1レコードの先頭35バイトを取り出す]
[byte[]]$crlf = @(13,10)
gc fixed150.txt -encoding byte -readcount 150  -totalcount (150*200) |%{$_[0..34] + $crlf} | sc out_Fixed150.txt -encoding byte


参考元

プログラマブルPowerShell ~プログラマのための活用バイブル
~ (.NET TECHNOLOGYシリーズ)
単行本(ソフトカバー) ? 2008/1/8
荒井 省三 (著)

単行本(ソフトカバー): 400ページ
出版社: 技術評論社 (2008/1/8)
言語: 日本語
ISBN-10: 4774133329
ISBN-13: 978-4774133324
発売日: 2008/1/8

3-2-5 バイナリファイルを処理する P240
より

 

<20181208追記STA>PowerShell SJIS固定長 改行(CrLf)なし 分割サンプル
※ハイスペックマシンでないと帰ってこないかも

 

[int[]]$arr = @(2,15,10,8,115);[byte[]]$crlf = @(13,10);[byte[]]$tab = @(9);$MAX=($arr.length -1)
gc fixed150.txt -encoding byte -readcount 150 -totalcount (150*200) |%{
$buf = $_
$j = 0
for($i=0;$i -lt $arr.length;$i++){
    $jx = $j + ($arr[$i] - 1)
    Write-Output $buf[$j..$jx]
    if($i -ne $MAX){Write-Output $tab}
    $j = $j + $arr[$i]
}
Write-Output $crlf} | sc out_Fixed150bbb.txt -encoding byte

 

<2行にしたもの>
[int[]]$arr = @(2,15,10,8,115);[byte[]]$crlf = @(13,10);[byte[]]$tab = @(9);$MAX=($arr.length -1)
measure-command{gc fixed150.txt -encoding byte -readcount 150 -totalcount (150*200) |%{$buf=$_;$j=0;for($i=0;$i -lt $arr.length;$i++){$jx=$j+($arr[$i]-1);Write-Output $buf[$j..$jx];if($i -ne $MAX){Write-Output $tab};$j=$j+$arr[$i];}Write-Output $crlf} | sc out_Fixed150.txt -encoding byte}

 

 <結果>
PS C:\Users\user\desktop> measure-command{gc fixed150.txt -encoding byte -readcount 150 -totalcount (150*200) |%{$buf=$
_;$j=0;for($i=0;$i -lt $arr.length;$i++){$jx=$j+($arr[$i]-1);Write-Output $buf[$j..$jx];if($i -ne $MAX){Write-Output $t
ab};$j=$j+$arr[$i];}Write-Output $crlf} | sc out_Fixed150.txt -encoding byte}

Days : 0

Hours : 0
Minutes : 0
Seconds : 5
Milliseconds : 825
Ticks : 58255296
TotalDays : 6.74251111111111E-05
TotalHours : 0.00161820266666667
TotalMinutes : 0.09709216
TotalSeconds : 5.8255296
TotalMilliseconds : 5825.5296

PS C:\Users\user\desktop>

 

<20181208追記END>


<20181209追記STA>

文字列を特定の長さで改行する方法
https://social.technet.microsoft.com/Forums/ja-JP/d962931a-55cc-4bc5-9661-d554c78137ae/25991233832101512434293052345012398382631237312391259133489212?forum=powershellja

<改変>version2.0ではSet-Content -encoding byteが遅いので速度いまいち。ファイルに書き出します。画面ではみれません。
[byte[]]$crlf=@(13,10)
$WindowSize = 150
$File = [System.IO.File]::OpenRead("C:\Users\user\Desktop\FIXED150.txt")
$Stream = New-Object System.IO.BinaryReader $File
0 .. (($File.Length - 1) / $WindowSize) |% { $Stream.ReadBytes($WindowSize) + $CrLf} | SC C:\Users\user\Desktop\OUT_FIXED150.txt -encoding byte;$File.close()


<いっそ.NETプログラミング版>ファイルに書き出します。画面ではみれません。
$len = 150
[byte[]]$crlf=@(13,10)
[byte[]]$buf     #(=>これは不要 要素数指定いらない) =@(0..($len-1))
$oFin = New-Object System.IO.Filestream ("C:\Users\user\Desktop\FIXED150.txt",[System.IO.FileMode]::Open)
$oBRin = New-Object System.IO.BinaryReader $oFin

$oFout = New-Object System.IO.Filestream ("C:\Users\user\Desktop\outFIXED150.txt",([System.IO.FileMode]::Create),([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout
while ($True){
    $buf = $oBRin.ReadBytes($len)
    if($buf.length -eq 0){
        break
    }else{
        $oBRout.Write($buf)
    }
    $oBRout.Write($crlf)
}

$oFin.Close();$oFout.Close();


 

<改変2>
[byte[]]$crlf=@(13,10)
$WindowSize = 150
$File = [System.IO.File]::OpenRead("C:\Users\user\Desktop\FIXED150.txt")
$Stream = New-Object System.IO.BinaryReader $File
$oFout = New-Object System.IO.Filestream ("C:\Users\user\Desktop\outFIXED150_999.txt",([System.IO.FileMode]::Create),([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout
0 .. (($File.Length - 1) / $WindowSize) |% { $oBRout.Write($Stream.ReadBytes($WindowSize)); $oBRout.Write($CrLf)} ;$File.close();$oFout.close();

<4件で試した結果>

PS C:\Users\user> $buf = $oBRin.ReadBytes($len)
PS C:\Users\user> $buf.length
150
PS C:\Users\user> $buf = $oBRin.ReadBytes($len)
PS C:\Users\user> $buf.length
150
PS C:\Users\user> $buf = $oBRin.ReadBytes($len)
PS C:\Users\user>
PS C:\Users\user> $buf.length
150
PS C:\Users\user> $buf = $oBRin.ReadBytes($len)
PS C:\Users\user> $buf.length
150
PS C:\Users\user> $buf = $oBRin.ReadBytes($len)
PS C:\Users\user> $buf.length
0

<20181209追記END>

 

<20181211追記STA><分割試行>[int[]]$arr = @(2,15,10,8,115)で

measure-command{
$len = 150
[byte[]]$crlf=@(13,10);[byte[]]$tab=@(9);
[byte[]]$buf #(=>これは不要 要素数指定いらない)=@(0..($len-1))
$oFin = New-Object System.IO.Filestream ("C:\Users\user\Desktop\Fixed150.txt",[System.IO.FileMode]::Open)
$oBRin = New-Object System.IO.BinaryReader $oFin

$oFout = New-Object System.IO.Filestream ("C:\Users\user\Desktop\oout.txt",([System.IO.FileMode]::Create), ([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout

while ($True){
    $buf = $oBRin.ReadBytes(2)
    if($buf.length -eq 0){
        break
    }else{
        $oBRout.Write($buf) ; $oBRout.Write($tab)
        $oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
        $oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
        $oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
        $oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($crlf)
    }
}
$oFin.Close();$oFout.Close();
}

 

Days : 0
Hours : 0
Minutes : 0
Seconds : 28
Milliseconds : 179

 <20181211追記END>

 <20181211追記2STA>

measure-command{
$len = 1500
[byte[]]$crlf=@(13,10);[byte[]]$tab=@(9);
[byte[]]$buf #(=>これは不要 要素数指定いらない)=@(0..($len-1))
$oFin = New-Object System.IO.Filestream ("C:\Users\user\Desktop\Fixed150.txt",[System.IO.FileMode]::Open)
$oBRin = New-Object System.IO.BinaryReader $oFin

$oFout = New-Object System.IO.Filestream ("C:\Users\user\Desktop\ooooooout.txt",([System.IO.FileMode]::Create),([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout

while ($True){
$buf = $oBRin.ReadBytes(2)
if($buf.length -eq 0){
break
}else{
$oBRout.Write($buf) ; $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($tab)

$oBRout.Write($oBRin.ReadBytes(002)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(015)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(010)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(008)); $oBRout.Write($tab)
$oBRout.Write($oBRin.ReadBytes(115)); $oBRout.Write($crlf)
}
}
$oFin.Close();$oFout.Close();
}

 <20181211追記2END>


 

<20181219追記STA>簡易版(少し遅くなります)
measure-command{
$len = 150
[int[]]$width = @(2,15,10,8,115)
$MAX  = ($width.length - 1)
[byte[]]$crlf=@(13,10);[byte[]]$tab=@(9);
[byte[]]$buf #(=>これは不要 要素数指定いらない)=@(0..($len-1))
$oFin   = New-Object System.IO.Filestream ("C:\Users\tkhs1732\Desktop\Fixed150.txt",[System.IO.FileMode]::Open)
$oBRin  = New-Object System.IO.BinaryReader $oFin

 

$oFout  = New-Object System.IO.Filestream ("C:\Users\tkhs1732\Desktop\oout2.txt",([System.IO.FileMode]::Create), ([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout

 

while ($True){
    $buf = $oBRin.ReadBytes($width[0])
    if($buf.length -eq 0){
        break
    }else{
        $oBRout.Write($buf) ; $oBRout.Write($tab)

 

        for($i=1;$i -lt $MAX;$i++){
            $oBRout.Write($oBRin.ReadBytes($width[$i])); $oBRout.Write($tab)
        }
        $oBRout.Write($oBRin.ReadBytes($width[$MAX]))  ; $oBRout.Write($crlf)
    }
}
$oFin.Close();$oFout.Close();
}

 <20181219追記END>

 

<20181220追記STA>簡易版(少し遅くなります)CrLfありの固定長の分割
measure-command{
$len = 150 + 2   #"+ 2"はCrLf分
[int[]]$width = @(2,15,10,8,115)
$MAX  = ($width.length - 1)
[byte[]]$crlf=@(13,10);[byte[]]$tab=@(9);
[byte[]]$buf #(=>これは不要 要素数指定いらない)=@(0..($len-1))
$oFin   = New-Object System.IO.Filestream ("C:\Users\tkhs1732\Desktop\crlfFixed150.txt",[System.IO.FileMode]::Open)
$oBRin  = New-Object System.IO.BinaryReader $oFin

$oFout  = New-Object System.IO.Filestream ("C:\Users\tkhs1732\Desktop\crlf_oout2.txt",([System.IO.FileMode]::Create), ([System.IO.FileAccess]::Write))
$oBRout = New-Object System.IO.BinaryWriter $oFout

while ($True){
    $buf = $oBRin.ReadBytes($width[0])
    if($buf.length -eq 0){
        break
    }else{
        $oBRout.Write($buf) ; $oBRout.Write($tab)

        for($i=1;$i -lt $MAX;$i++){
            $oBRout.Write($oBRin.ReadBytes($width[$i])); $oBRout.Write($tab)
        }
        $oBRout.Write($oBRin.ReadBytes($width[$MAX]))  ; $oBRout.Write($crlf)
        $DUMMY = $oBRin.ReadBytes(2) #末尾のCrLf分を読み取るだけの処理
    }
}
$oFin.Close();$oFout.Close();
}


<20181220追記END>