2011-02-18 25 views
2

夥計。 我試圖從一些非文本文件中獲取文件版本。 在它們中的每一箇中(大約在開頭)都有幾行文本行包含有關該文件的信息。 例如:如何在Windows中使用批處理命令從非文本文件獲取一些文本信息?

[some nontext data (very few)] 
version: 455467 
build date: 23.11.2010 
..... 
[rest of the nontext data] 

如果你想,我會盡量讓這樣的文件,但我不能告訴你的原始文件(我的公司也不會允許它)。對不起......

我試過這段代碼:

@echo off 
for /f "tokens=1,2" %%A in (file.dat) do if %%A==version: (set version=%%B 
goto found) 
echo not found 
goto end 
:found 
echo found: %version% 
:end 
pause 

但它只能當「FILE.DAT」是一個文本文件,如果沒有我得到「未找到」。 如果我用'type file.dat'替換file.dat,它不會返回(處理器使用率爲100%)。 如果我用'find/i'版本替換file.dat:「file.dat'它可以工作,但是非常非常緩慢(分鐘)。由於我必須處理許多文件,而且我很少有時間無法使用它。如果我用查看器和複製版本號手動輸入每個文件,它的工作速度會快很多;但問題是,我想有一個cmd做...

哦,我不能在那裏我工作在計算機上安裝其他程序....

的操作系統是Windows XP x86。

請幫幫我。 謝謝。

最好的問候,科斯明

後來編輯: 我有「建造」一個測試文件,所以每個人都可以看到和測試:http://www.mediafire.com/download.php?r0x5702lkv14jro 這是非常小的(真正的文件有幾十個,有的甚至上百MB的)。

稍後更改編輯:測試文件對於測試IF是否有用如果代碼找到數字,但它非常小,它並不能讓您知道真實數據文件需要多少時間。但是您可以這樣做:測量測試文件的掃描時間並乘以「100 MB/2088 Bytes」= 50 219.例如,這適用於「find」。 「類型」更慢(我認爲它是指數級的,而不是liniar)。

+0

什麼操作系統版本?看起來像PowerShell的工作,而不是普通的舊MS-DOS批處理文件。 Windows XP和Windows Server 2003 - 下載並安裝PowerShell V1和V2版本(作爲OS修補程序有效)。 Windows Server 2008 - PowerShell v1是一個'功能',可以添加。下載並安裝PowerShell V2版本(作爲OS修補程序有效)。 Windows 7/Windows Server 2008 R2 - PowerShell V2默認安裝。 – 2011-02-18 03:38:34

+0

Windows XP。但是,正如我所說的,我無法在該計算機上安裝其他程序,甚至無法在PowerShell上安裝其他程序。但是,謝謝你的想法。 – Cosmin 2011-02-18 03:46:17

回答

0

如果在「版本」前有二進制數據,你的IF不能工作。
由於%% A的內容與「{binary}版本類似:」

請試試看,它測試字符串「version」是否在行中的任何位置。 如果你有「!」在你的二進制數據中,它可能會失敗,那麼解決方案必須被削減。

setlocal EnableDelayedExpansion 
for /f "tokens=* delims=" %%A in ('type file.dat') do (
    set "line=%%A" 
    set "version=!line:*version=!" 
    if "!line!" NEQ "!version!" (
     goto found 
    ) 
) 
echo not found 
goto end 
:found 
echo found: %version% 
:end 

編輯:

for /f "tokens=* delims=" %%A in (file.dat) do (... 

在一個正常的循環,主要的問題是十六進制碼0×00,因爲它是在一條線上找到,文件讀取立即停止。

但是類型更多可以抑制這一點。

2

我使用了jeb的FC讀取二進制技術的簡化版本來讀取DAT文件的前1024個字節。 (converting a binary file to HEX representation using batch file)我只保留可打印的ASCII字符和< LF>,剩下的我扔掉了。我使用了包含1024個退格>字符的比較文件,這樣我就不必擔心FC輸出中的空白。

我使用我爲我的hexDump.bat例程(http://www.dostips.com/forum/viewtopic.php?p=7038)開發的映射將十六進制表示轉換回ASCII字符。

然後,所有剩下的就是一些簡單的字符串操作來解析版本。我尋找<LF>version:,剝去前導空格,然後取所有可打印字符,直到下一個<LF>作爲版本值。

此解決方案假定版本位於前1024個字符內。只需增加比較文件的大小,就可以擴展爲支持第一個8k。

解決方案似乎很快,DAT文件的大小應該不會影響性能。

@echo off 
setlocal enableDelayedExpansion 

:: Build a binary file containing 1024 <backSpace> characters 
set compareFile="BS1024.DAT" 
if not exist %compareFile% (
    for /f "tokens=1 delims=# " %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
    <nul set/p"=%%a" >%compareFile% 
) 
    for /l %%n in (1 1 10) do type %compareFile% >>%compareFile% 
) 

:: Create a variable containing <lineFeed> character (0x0A) 
set lf=^ 


:: Above 2 blank lines are critical - do not remove. 

:: Grab the first 1024 bytes, preserving only printable ASCII characters and <lineFeed> 
set map= ^^^!^"#$%%^&'^(^)*+,-./:;^<=^>[email protected][\]^^^^_`abcdefghijklmnopqrstuvwxyz{^|}~ 
set datFile="test.dat" 
set "dat=" 
for /f "eol=F usebackq tokens=2 skip=1 delims=:[] " %%A in (`fc /b %datFile% %compareFile%`) do (
    if "%%A"=="0A" (set "dat=!dat!!lf!") else (
    set /a "n=0x%%A-32" 
    if !n! geq 0 if !n! leq 94 for %%n in (!n!) do set "dat=!dat!!map:~%%n,1!" 
) 
) 

:: Find the version line and get the value 
set "version=" 
for %%C in ("!lf!") do set "dat2=!dat:*%%~Cversion:=!" 
if "!dat2!" neq "!dat!" (
    for /f "tokens=* eol= delims= " %%A in ("!dat2!") do (
    set "version=%%A" 
    goto :done 
) 
) 
:done 
set version 
相關問題