我正在我們的Linux盒子上執行一些相當直接的校驗,但我現在需要為我們的Windows用戶重新創建類似的東西。為了給我一個單一的校驗,我只需運行:
md5sum *.txt | awk '{ print $1 }'/span> | md5sum
我很難在Windows中重新創建這個,無論是用批處理檔案還是Powershell。我得到的最接近的結果是:
Get-ChildItem $path -Filter *.txt !
Foreach-Object {
$hash = Get-FileHash -Algorithm MD5 -Path ($path " $_) | 選擇 -擴展屬性"Hash"
$hash = $hash.tolower() #Get-FileHash回傳大寫的校驗和,linux回傳小寫(!)
Write-host $hash。
}
這將把每個檔案的校驗結果列印到控制臺,與linux命令相同,但把它輸回給Get-FileHash,以獲得與linux等價物相匹配的單一輸出,這讓我摸不著頭腦。寫入檔案時,我被回車鍵的差異所困擾
。以字串的形式流回Get-FileHash不會回傳相同的校驗值:
$String = Get-FileHash -Algorithm MD5 - Path (Get-ChildItem -path $files -Recurse) | Select -ExpandProperty "Hash"
$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write($stringAsStream)
Get-FileHash -Algorithm MD5 -InputStream $stringAsStream。
我是否過度設計了這個?我相信這不應該是這么復雜的! TIA
uj5u.com熱心網友回復:
你需要參考.Hash屬性在Get-FileHash回傳的物件上。如果你想要一個類似于md5hash的視圖,你也可以使用Select-Object來策劃:
# Get filehashes in $path with similar output to md5sum
$fileHashes = Get-ChildItem $path -File | Get-FileHash -Algorithm MD5
# 一旦你有了哈希值,你就可以按以下方式參考這些屬性。
# .Algorithm是散列演算法。
# .Hash是實際的檔案哈希值。
# .Path是檔案的完整路徑。
foreach( $hash in $fileHashes ) {
"$($hash.Algorithm):$($hash.Hash) ( $($hash.Path))"
對于$path中的每個檔案,上述foreach回圈將產生一個類似的行:
MD5:B4976887F256A26B59A9D97656BF2078 (C:Usersusernamedlinstaller.msi)
演算法、哈希值和檔案名顯然將根據你選擇的哈希演算法和檔案系統而有所不同。
uj5u.com熱心網友回復:
魔鬼就在細節中:
(已經知道)Get-FileHash回傳大寫的校驗和,而Linuxmd5sum是小寫的(!);
*.txt在PowerShell中不區分大小寫,而在Linux中則取決于nocaseglob選項。如果設定了(shopt -s nocaseglob),那么Bash在進行檔案名擴展時就會以不區分大小寫的方式匹配檔案名。否則(shopt -u nocaseglob),檔案名匹配是大小寫敏感的;Get-ChildItem輸出根據Unicode整理演算法排序,而在Linux中*.txt過濾器按照LC_COLLATE類別(LC_COLLATE="C.UTF-8"在我的系統上)的順序展開。在以下(部分注釋)腳本中,三個# Test塊展示了我對最終解決方案的除錯步驟:
Function Get-StringHash{
[OutputType([System.String]) ]
param(
# 命名或定位:一個字串。
[Parameter(Position=0]]
[string]$InputObject。
)
$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write( $InputObject)
$writer.Flush()
$stringAsStream.Position = 0。
Get-FileHash -Algorithm MD5 -InputStream $stringAsStream !
Select-Object -ExpandProperty Hash
$writer.Close()
$writer.Dispose()
$stringAsStream.Close()
$stringAsStream.Dispose()
}
function ConvertTo-Utf8String{
[OutputType([System.String]) ]
param(
# 命名或定位:一個字串。
[Parameter(Position=0, Mandatory=$false)]
[string]$InputObject = '')
)
開始 {
$InChars = [char[]]$InputObject
$InChLen = $InChars.Count
$AuxU_8 = [System.Collections.ArrayList]::new()
}
程序 {
for ($ii= 0; $ii -lt $InChLen; $ii ) {
if ( [char]::IsHighSurrogate( $InChars[$ii]) -and
( 1 $ii) -lt$InChLen -and
[char]::IsLowSurrogate( $InChars[1 $ii] ) ) {
$s = [char]::ConvertFromUtf32(
[char]:: ConvertToUtf32( $InChars[$ii], $InChars[1 $ii] )
$ii
} else {
$s = $InChars[$ii]
}
[void]$AuxU_8.Add(
([System.Text.UTF32Encoding]::UTF8.GetBytes($s) |)
ForEach-Object { '{0:X2}' -f $_}) -join '
)
}
}
end { $AuxU_8 -join '' }
}
#設定變數
$hashUbuntu = '5d944e44149fece685d3eb71fb94e71b'/span>
$hashUbuntu <# copied from 'Ubuntu 20.04 LTS' in Wsl2:
cd `wslpath -a 'D:at''。
md5sum *.txt | awk '{ print $1 }' | md5sum | awk '{ print $1 }'
<##>
$LF = [char]0x0A # 換行(LF)
$path = 'D:Bat' # testing directory。
$filenames = 'D:atmd5sum_Ubuntu_awk.lst'
<#從Wsl2中的'Ubuntu 20.04 LTS'獲得:
cd `wslpath -a 'D:at''。
md5sum *.txt | awk '{ print $1 }'/span> > md5sum_Ubuntu_awk.lst
md5sum md5sum_Ubuntu_awk.lst | awk '{ print $1 }' # 以供參考。
<##>
# Test #1: `Get-FileHash`是否相同(超越字符大小寫)?
$hashFile = Get-FileHash -Algorithm MD5 -Path $filenames !
Select-Object -ExpandProperty Hash
$hashFile.ToLower() -ceq $hashUbuntu.
# Test #2: `$stringToHash`是否定義良好? `Get-StringHash`是否相同?
$hashArray = Get-Content $filenames -Encoding UTF8
$stringToHash = ($hashArray -join $LF) $LF -join $LF
(Get-StringHash -InputObject $stringToHash) -eq $hashUbuntu (Get-StringHash -InputObject $stringToHash)
# Test #3: Another check: is `Get-StringHash` the same?
推進位置 -路徑 $path
$filesInBashOrder = bash.exe -c "ls -1 *.txt"
$hashArray = $filesInBashOrder !
Foreach-Object {
$hash = Get-FileHash -Algorithm MD5 -Path (
Join-Path -Path $path -ChildPath $_) |
Select-Object -ExpandProperty "Hash"。
$hash.tolower()
}
$stringToHash = ($hashArray -join $LF) $LF -join $LF
(Get-StringHash -InputObject $stringToHash) -eq $hashUbuntu (Get-StringHash -InputObject $stringToHash)
流行定位
# Solution - Ordinal order assuming `LC_COLLATE="C.UTF-8"` in Linux。
推動定位 -路徑 $path
$hashArray = Get-ChildItem -Filter *.txt -Force -ErrorAction SilentlyContinue||。
Where-Object {$_.Name -clike "*.txt"}。| # only if `shopt -u nocaseglob`。
Sort-Object -Property { (ConvertTo-Utf8String -InputObject $_.Name) } |
Get-FileHash -Algorithm MD5|
Select-Object -ExpandProperty "Hash" !
Foreach-Object {
$_.ToLower()
}
$stringToHash = ($hashArray -join $LF) $LF -join $LF
(Get-StringHash -InputObject $stringToHash).ToLower() -ceq $hashUbuntu。
流行-定位
輸出(在278個檔案上測驗)。.SO69181414.ps1
5d944e44149fece685d3eb71fb94e71b
真
真
True True
True True
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/309309.html
標籤:
上一篇:Powershell的if陳述句進入csv的foreach回圈中
下一篇:將數學運算子分配給變數-PS
