簡體   English   中英

使用Windows命令提示符查找大文本文件的總行數時出錯

[英]error of finding the total line number of a large text file using the Windows command prompt

我想使用Windows命令提示符查找文本文件的總行號(> 60 GB)。

我用了:

 findstr /R /N "^" file.txt | find /C ":"

但是,返回的結果是負數。 它溢出了嗎? 文件的行數不超過50億行。 對於整數(4字節),其最大范圍為−2,147,483,648至2,147,483,647。 因此,我需要設計一個腳本以將結果除以1000來計算數量?

如果是,請幫助我設計Windows批處理文件。

您可以嘗試使用JScript解決方案。 JavaScript數字始終是64位浮點數據類型 ,最多可以精確到15位整數。 不過要花一點時間。 用此腳本計算100兆XML文件中的行數大約需要15秒。

編輯:由於float數據類型不夠大,我修改了腳本以使用數組作為計數器,然后將結果輸出為連接的字符串。 只要fso.OpenTextFile().SkipLine()不會阻塞(對此沒有解決方案,而是嘗試使用其他語言,也許是Python或Perl?),這應該可以工作,並且希望它不會太昂貴對性能的打擊。 我在4.3 gig ISO文件上進行了測試,大約用了8分鍾。

@if (@a==@b) @end /*

:: countlines.bat
:: usage: countlines.bat filetocount.log

:: batch portion does nothing remarkable
:: but relaunches itself with jscript interpreter
@echo off

cscript /nologo /e:jscript "%~f0" "%~f1"

goto :EOF

:: end of batch / begin JScript */

var fso, f, file = WSH.Arguments(0), longVal = [0],
ForReading = 1, ForWriting = 2, b4 = new Date();

// inherits global array longVal[]
// increments each element from right to left
function inc() {
    for (var i=longVal.length - 1; i>=0; i--) {
        if (++longVal[i] == 10) {
            longVal[i] = 0;
            if (!i) {
                longVal.splice(0, 0, 0);
                i++;
            }
            continue;
        }
        else break;
    }
}

fso = new ActiveXObject("Scripting.FileSystemObject");
f = fso.OpenTextFile(file, ForReading);
while (!f.AtEndOfStream) {
    f.SkipLine();
    inc();
}
WSH.Echo(longVal.join(''));
f.Close();

var stopwatch = 'Line count completed in ' + ((new Date() - b4) / 1000.0) + 's';
WSH.StdErr.WriteLine(stopwatch);

這是一個蝙蝠文件來計算行數。 是的,您達到了32位int限制,並且set / a計算也會發生同樣的事情……因此某種划分當然是個好主意。

@echo off
setlocal ENABLEDELAYEDEXPANSION

set Singles=0
set Thousands=0
for /f "tokens=1,* delims=:" %%a in ('findstr /nr "^" "%1"') do (
    rem echo %%a   %%b
    set /a Singles+=1
    if !Singles! equ 1000 (
        set /a Thousands+=1
        set Singles=0
    )
)
set Singles=x000%Singles%
echo %Thousands%.%Singles:~-3% thousand lines

我包括了rem行,以便您可以根據需要檢查findstr的輸出。

---好的,所以bat文件的解決方案很慢---

這是一個可能會盡快獲得的vb(可能甚至比findstr / find時間還要好?)要運行:您可以只使用: scriptname.vbs filename將結果輸出到屏幕或cscript -nologo scriptname.vbs filename ,以在命令提示符下輸出。

這是如何工作的簡短摘要。 文本流具有Line屬性,該屬性是32位帶符號的int。 只要我們檢測到從+到-以及-到+的每個開關,就可以使用final file.Line屬性計算總行數。

if WScript.Arguments.Count = 0 then
    WScript.Echo "Missing filename parameter"
    WScript.Quit
end if

Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const bytesToSkip = 2000000000
Dim fso, MyFile, count, direction, position, totalSize
Set fso = CreateObject("Scripting.FileSystemObject")

' Open the file to count.
Set MyFile = fso.OpenTextFile(WScript.Arguments(0), ForReading)

totalSize = fso.GetFile(WScript.Arguments(0)).Size
count=0
direction=1
position=0

' Jump through the file in big blocks
Do While position < totalSize
    MyFile.Skip(bytesToSkip) 'If going past of the end of the file, this doesn't error the first time
    position = position + bytesToSkip

    if MyFile.Line = 0 and direction=-1 Then
        ' Have wrapped back to 0
        count=count+1
        direction=1
    elseif direction <> abs(MyFile.Line)/MyFile.Line Then
        'Count each change from + to - or - to +
        count=count+1
        direction=direction*(-1)
    end if
    REM WScript.Echo direction & "    " & position & "    " & MyFile.Line & "    " & count
Loop

' Do final calculations
if MyFile.Line = 0 Then
    Count = Count*(2^31)
elseif direction = 1 Then
    count=Count*(2^31) + MyFile.Line
elseif direction = -1 Then
    count=Count*(2^31) + (2^31 + MyFile.Line)
end if

MyFile.Close

WScript.Echo "Total Lines = " & count

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM