有馬総一郎のブログ

(彼氏の事情)

2015年01月26日 23:40:00 JST - 1 minute read - PowerShell

powershellで先頭8バイトを読み込んでPNGファイルか判定する

音楽フォルダ内のfolder.jpgにpngファイルが混じってないか、調べる。 PNG識別部は0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0Aなので十進数に変換して判定する。

GetPngList.PS1

Set-Location "C:\Users\arimasou16\Music"
$logfile = "C:\Users\arimasou16\Documents\" + "pngpath_" + (Get-Date -Format "yyyyMMdd") + ".log"
$files = Get-ChildItem -filter folder.jpg -Recurse
foreach ($file in $files) {
  $byteBuffer = New-Object System.Byte[] 8
  $reader = [System.IO.File]::OpenRead($file.Fullname)
  $bytesRead = $reader.Read($byteBuffer, 0, 8)
  if ($bytesRead -eq 8 -and
              $byteBuffer[0] -eq 137 -and
              $byteBuffer[1] -eq 80 -and
              $byteBuffer[2] -eq 78 -and
              $byteBuffer[3] -eq 71 -and
              $byteBuffer[4] -eq 13 -and
              $byteBuffer[5] -eq 10 -and
              $byteBuffer[6] -eq 26 -and
              $byteBuffer[7] -eq 10) {
    Write-Output $file.Fullname | Out-File ${logfile} -Append -Encoding UTF8
  }
}
C:\Users\arimasou16\Music\Björk\Post\folder.jpg
C:\Users\arimasou16\Music\소녀시대\THE BEST\folder.jpg

とかSJISで表示できないパスのファイルも出力された。文字コードはUTF8、BOM付き。

$bFile = Get-Content "C:\Users\arimasou16\Photos\picture.png" -Encoding Byte -TotalCount 8
echo $bFile[0]
echo $bFile[1]
echo $bFile[2]
echo $bFile[3]
echo $bFile[4]

でも判別できたけど、foreach で回そうとすると何故か上手く行かなかった。 出力したログファイルを読み込んで、拡張子をpngに置換する。

Get-Content "C:\Users\arimasou16\Documents\pngpath_20150126.log" | ForEach { Move-Item -LiteralPath  $_ -Destination ($_ -replace '.jpg', '.png') }