2017-02-08 7 views
-2

Я искал обширный Интернет и не могу найти способ поиска конкретных слов в и только в последних 10 строках текстового файла с использованием пакетного кода. Пока у меня есть это, которое ищет текст во всем файле.Как найти конкретные слова в последних десяти строках файла с партией

>nul find "Example Words" examplefile.txt && (
REM Found... 
goto next) || (
REM Not Found... 
goto home 
) 

Итак, опять же, что это делает он ищет файл всего для Примера слов, а то, что мне нужно, это способ, чтобы искать эти слова в только последних 10 строк?

+0

Это последние ** 10 ** или последние ** 2 ** линии? просьба уточнить! – aschipfl

+1

@aschipfl: Существует 10 типов людей: те, которые знают двоичную систему, и те, которые не ... – Aacini

+0

Хе-хе, @ Аасини ... Надеюсь, что ОП разъяснит, хотя ... – aschipfl

ответ

0

Во-первых, подсчитать количество строк, содержащихся в текстовом файле:

for /F %%C in ('^< "examplefile.txt" find /C /V ""') do set "COUNT=%%C" 

Затем определить, сколько строк должны быть пропущены (все, кроме последних 10 строк, например):

if %COUNT% GTR 10 (set /A "SKIP=COUNT-10") else (set "SKIP=0") 

Наконец, используйте more command на самом деле пропустить следующие строки:

more +%SKIP% "examplefile.txt" | > nul findstr /L /I "Example Words" && (
    rem Found 
    goto next 
) || (
    rem Not Found 
    goto home 
) 

Использование findstr вместо find указать несколько пространства -разделенное строки поиска или слова (например, Example и Words здесь). Используйте опцию /I для поиска без учета регистра.

Обратите внимание, что more ожидает ввода пользователем, когда входные файлы содержат 65535 или более строк. Он преобразует ПРОСТРАНСТВА в TABs, но это ничего не меняет, поскольку вы все равно не заинтересованы в них, так как ищете только слова.


Вот более сложный и менее эффективный подход опираясь на for /F loop, используя также переменную COUNT как получено выше.Он нуждается в skip вариант for /F, который строят следующим образом:

set /A "SKIP=COUNT-10" 
if %SKIP% GTR 0 (set "SKIP=skip=%SKIP%") else (set "SKIP=") 

Тогда есть вышеупомянутый for /F петля:

for /F "%SKIP% delims=" %%L in ("examplefile.txt") do (
    echo(%%L| > nul findstr /L /I "Example Words" && (
     rem Found 
     goto next 
    ) 
) 
ren Not Found 
goto home 

Каждая строка ищется индивидуально в цикле; как только встречается совпадение, выполняется goto next; goto разбивает контекст цикла, поэтому for /F больше не выполняет какие-либо команды внутри своего тела.

Относительно того, что for /F игнорирует пустые строки, а также такое начало с точкой с запятой (;) по умолчанию. Некоторые специальные символы (^, &, (, ), ", <, >, |) может вызвать проблемы с echo команды в трубе (|).

+0

Кажется, что это не работает. Всякий раз, когда я добавляю это в свой код, он мгновенно закрывается. – R2bEEaton

+0

Что вы добавили в свой код, и в чем проблема? – aschipfl

+0

В этом я заменил раздел после: AfterQPos с ... 'for/F %% C in ('^ <"% Appdata% \. Minecraft \ logs \ latest.log "find/C') установить" COUNT = %% C "' New Line ', если% COUNT% GTR 10 (set/A" SKIP = COUNT-10 ") else (установить" SKIP = ")' New Line 'more +% SKIP%"% appdata% \. Minecraft \ logs \ last.log "| > nul findstr/L/I «Подключение к серверу ...» && ( rem Найдено goto next ) || ( не найден goto home ) 'Когда я это делаю, вместо того, чтобы повторять, пока не найдет слова, он мгновенно закрывается. – R2bEEaton

0

Включает/исключает n строк сверху или снизу файла.

Cut

filter cut {t|b} {i|x} NumOfLines 

сокращает количество линий от верхней или нижней части файла.

t - top of the file 
b - bottom of the file 
i - include n lines 
x - exclude n lines 

Пример

cscript //nologo c:\folder\filter.vbs cut t i 5 < "%systemroot%\win.ini" 

Сценарий filter.vbs

Set Arg = WScript.Arguments 
set WshShell = createObject("Wscript.Shell") 
Set Inp = WScript.Stdin 
Set Outp = Wscript.Stdout 
Set rs = CreateObject("ADODB.Recordset") 
With rs 
    .Fields.Append "LineNumber", 4 

    .Fields.Append "Txt", 201, 5000 
    .Open 
    LineCount = 0 
    Do Until Inp.AtEndOfStream 
     LineCount = LineCount + 1 
     .AddNew 
     .Fields("LineNumber").value = LineCount 
     .Fields("Txt").value = Inp.readline 
     .UpDate 
    Loop 

    .Sort = "LineNumber ASC" 

    If LCase(Arg(1)) = "t" then 
     If LCase(Arg(2)) = "i" then 
      .filter = "LineNumber < " & LCase(Arg(3)) + 1 
     ElseIf LCase(Arg(2)) = "x" then 
      .filter = "LineNumber > " & LCase(Arg(3)) 
     End If 
    ElseIf LCase(Arg(1)) = "b" then 
     If LCase(Arg(2)) = "i" then 
      .filter = "LineNumber > " & LineCount - LCase(Arg(3)) 
     ElseIf LCase(Arg(2)) = "x" then 
      .filter = "LineNumber < " & LineCount - LCase(Arg(3)) + 1 
     End If 
    End If 

    Do While not .EOF 
     Outp.writeline .Fields("Txt").Value 

     .MoveNext 
    Loop 
End With 

Вот пример кода подсчета папки путем подсчета строк на выходе в dir команды.

@SETLOCAL ENABLEDELAYEDEXPANSION 
@CD C:\newfolder 
@set count=0 
@For /f "delims=" %%A in ('dir C:\newfolder\*.* /ad /s /b') Do (
    set /a count=!count!+1 
@rem  If !Count! gtr 1 echo Num of folders 
) 

Set /a num=%random% %% %Count% + 1 
Echo %num% 

@For /f "skip=%num% delims=" %%A in ('dir C:\newfolder\*.* /ad /s /b') Do (
Echo this is nth random folder 
Echo Copy "%~dpnx0" "%%A" 
Exit /b 
) 
+0

Просто, чтобы уточнить, нет ли способа сделать это в пакетном режиме? – R2bEEaton

+0

Потому что есть. Это будет болезненно медленным. – Freddie

+0

Используйте цикл 'for/f', подсчитайте строки в режиме с задержкой расширения, прочитайте файл во второй раз с' for/f', отбрасывая все, кроме последних n строк, разработанных на шаге 1. – Freddie