在批处理文件中显示文本文件中的行

时间:2023-01-19 18:55:46

I'm tryin' to find a script that will let me display "linenumber# and linenumber# as well as lines#-#" from a text file in a batch file? I found this script here on this site..

我正在试着找到一个脚本,让我在批处理文件中的文本文件中显示“linenumber#和linenumber#以及# - #”行?我在这个网站上找到了这个脚本..

@echo off
setlocal enabledelayedexpansion
if [%1] == [] goto usage
if [%2] == [] goto usage

SET /a counter=0

for /f "usebackq delims=" %%a in (%2) do (
if "!counter!"=="%1" goto exit
echo %%a
set /a counter+=1
)

goto exit

:usage
echo Usage: head.bat COUNT FILENAME

:exit

And it works great :) But it grabs the number of lines from the top of the text file. I want to be able to display certain lines in the text file, as well as a range if possible..

并且效果很好:)但是它从文本文件的顶部抓取了行数。我希望能够在文本文件中显示某些行,以及可能的范围。

EG: I have a text file with 30 lines, and I want to display lines 1-4; 7-11; 13; 17-20; 22; 26 & 29

EG:我有一个30行的文本文件,我想显示1-4行; 7-11; 13; 17-20; 22; 26和29

2 个解决方案

#1


Here's a simple modification of the sample batch file above. Copy the code below to file and name it "LineDisplay.bat" - it takes the FirstLineNumber and LastLineNumber as parameters. Example: LineDisplay test.txt 12 30 (to read lines 12-30)

这是上面的示例批处理文件的简单修改。将下面的代码复制到文件并将其命名为“LineDisplay.bat” - 它将FirstLineNumber和LastLineNumber作为参数。示例:LineDisplay test.txt 12 30(读取第12-30行)

@echo off
setlocal enabledelayedexpansion
if [%1] == [] goto usage
if [%2] == [] goto usage
if [%3] == [] goto usage

set /a FirstLineNumber = %2
set /a LastLineNumber = %3

echo Reading from Line !FirstLineNumber! to !LastLineNumber!


SET /a counter=1

for /f "usebackq delims=" %%a in (%1) do (
    if !counter! GTR !LastLineNumber! goto exit
    if !counter! GEQ !FirstLineNumber! echo !counter! %%a
    set /a counter+=1
)

goto exit

:usage
echo Usage: LineDisplay.bat FILENAME FirstLineNumber LastLineNumber

:exit

Here's a line to a nice tutorial on creating batch files http://vtatila.kapsi.fi/batch_tutorial.html

这是关于创建批处理文件的精彩教程的一行http://vtatila.kapsi.fi/batch_tutorial.html

#2


Seems to work:

似乎工作:

@ECHO OFF
REM Show usage and quit if no file name was given
IF [%1]==[] GOTO USAGE
REM Show entire file if no range was given
IF [%2]==[] TYPE %1 & GOTO :EOF

SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

SET FILENAME=%1
SET LASTLINE=0

REM Build the array of lines to display
SHIFT
:RANGEREADLOOP
CALL :BUILDARRAY %1
SHIFT
IF NOT [%1]==[] GOTO RANGEREADLOOP

REM Loop through the file and keep track of the lines to display
SET CURRENTLINE=0
SET INDEX=1
FOR /F "delims=" %%l in (%FILENAME%) DO (
    SET LINE=%%l
    CALL :PRINTLINE
)

GOTO :EOF

REM Adds the lines from the specified range to the array of lines to display
:BUILDARRAY
    REM Find out whether we have a single line or a range
    SET TEST=%1
    SET /A TEST1=%TEST%
    SET /A TEST2=%TEST:-=%
    IF %TEST1%==%TEST2% (
        REM Single line
        SET /A LASTLINE+=1
        SET LINES[!LASTLINE!]=%1
    ) ELSE (
        REM Range
        FOR /F "tokens=1,2 delims=-" %%x IN ("%1") DO (SET RANGESTART=%%x&SET RANGEEND=%%y)
        REM Some sanity checking
        IF !RANGESTART! GTR !RANGEEND! (
            ECHO.Problem with range !RANGESTART!-!RANGEEND!:
            ECHO.  Ranges must have a start value smaller than the end value.
            EXIT /B 1
        ) ELSE (
            FOR /L %%i IN (!RANGESTART!,1,!RANGEEND!) DO (
                SET /A LASTLINE+=1
                SET LINES[!LASTLINE!]=%%i
            )
        )
    )
GOTO :EOF

REM Prints the specified line if the current line should be printed
:PRINTLINE
    SET /A CURRENTLINE+=1
    IF %CURRENTLINE%==!LINES[%INDEX%]! (
        REM We have a line to print, so do this
        ECHO !LINE!
        SET /A INDEX+=1
    )
GOTO :EOF

REM Prints usage and exits the batch file
:USAGE
    ECHO.%~n0 - Displays selected lines from a text file.
    ECHO.
    ECHO.Usage:
    ECHO.  %~n0 ^<filename^> ^<range^> ...
    ECHO.
    ECHO.  ^<filename^> - the text file from which to read
    ECHO.  ^<range^>    - the line range(s) to display.
    ECHO.
    ECHO.Example:
    ECHO.  %~n0 foo.txt 1-4 13 15 18-20
    ECHO.
    ECHO.  will display the first four lines from the file "foo.txt",
    ECHO.  the 13th and 15th as well as the lines 18 to 20.
    ECHO.
    ECHO.Line ranges are separated by comma, semicolon or space. If no range is given,
    ECHO.the entire file is displayed.
    EXIT /B 1
GOTO :EOF

The whole script could use some better error checking, examples of what not to do or where error checking is a bit wonky:

整个脚本可以使用一些更好的错误检查,不做的例子或错误检查有点不稳定的例子:

  • dl foo.txt 1-2-4 (prints lines 1-2 but no error message)
  • dl foo.txt 1-2-4(打印1-2行,但没有错误信息)

  • dl foo.txt -1 (error message that the range 1- isn't correct)
  • dl foo.txt -1(范围1-不正确的错误消息)

Other limitations:

  • Ranges must be sorted. With the current implementation there is no way to do something like dl foo.txt 7-8,1-2.
  • 范围必须排序。在目前的实现中,没有办法像dl foo.txt 7-8,1-2那样做。

  • No line may be selected twice. Something like dl foo.txt 1,2,2-8,11-15 will stop after the second line.
  • 不能选择两行。 dl foo.txt 1,2,2-8,11-15之类的东西会在第二行之后停止。

  • No support for UNIX-style line endings (U+000A)
  • 不支持UNIX样式的行结尾(U + 000A)

EDIT: Fixed an issue with files that contain parentheses.

编辑:修复了包含括号的文件的问题。

#1


Here's a simple modification of the sample batch file above. Copy the code below to file and name it "LineDisplay.bat" - it takes the FirstLineNumber and LastLineNumber as parameters. Example: LineDisplay test.txt 12 30 (to read lines 12-30)

这是上面的示例批处理文件的简单修改。将下面的代码复制到文件并将其命名为“LineDisplay.bat” - 它将FirstLineNumber和LastLineNumber作为参数。示例:LineDisplay test.txt 12 30(读取第12-30行)

@echo off
setlocal enabledelayedexpansion
if [%1] == [] goto usage
if [%2] == [] goto usage
if [%3] == [] goto usage

set /a FirstLineNumber = %2
set /a LastLineNumber = %3

echo Reading from Line !FirstLineNumber! to !LastLineNumber!


SET /a counter=1

for /f "usebackq delims=" %%a in (%1) do (
    if !counter! GTR !LastLineNumber! goto exit
    if !counter! GEQ !FirstLineNumber! echo !counter! %%a
    set /a counter+=1
)

goto exit

:usage
echo Usage: LineDisplay.bat FILENAME FirstLineNumber LastLineNumber

:exit

Here's a line to a nice tutorial on creating batch files http://vtatila.kapsi.fi/batch_tutorial.html

这是关于创建批处理文件的精彩教程的一行http://vtatila.kapsi.fi/batch_tutorial.html

#2


Seems to work:

似乎工作:

@ECHO OFF
REM Show usage and quit if no file name was given
IF [%1]==[] GOTO USAGE
REM Show entire file if no range was given
IF [%2]==[] TYPE %1 & GOTO :EOF

SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

SET FILENAME=%1
SET LASTLINE=0

REM Build the array of lines to display
SHIFT
:RANGEREADLOOP
CALL :BUILDARRAY %1
SHIFT
IF NOT [%1]==[] GOTO RANGEREADLOOP

REM Loop through the file and keep track of the lines to display
SET CURRENTLINE=0
SET INDEX=1
FOR /F "delims=" %%l in (%FILENAME%) DO (
    SET LINE=%%l
    CALL :PRINTLINE
)

GOTO :EOF

REM Adds the lines from the specified range to the array of lines to display
:BUILDARRAY
    REM Find out whether we have a single line or a range
    SET TEST=%1
    SET /A TEST1=%TEST%
    SET /A TEST2=%TEST:-=%
    IF %TEST1%==%TEST2% (
        REM Single line
        SET /A LASTLINE+=1
        SET LINES[!LASTLINE!]=%1
    ) ELSE (
        REM Range
        FOR /F "tokens=1,2 delims=-" %%x IN ("%1") DO (SET RANGESTART=%%x&SET RANGEEND=%%y)
        REM Some sanity checking
        IF !RANGESTART! GTR !RANGEEND! (
            ECHO.Problem with range !RANGESTART!-!RANGEEND!:
            ECHO.  Ranges must have a start value smaller than the end value.
            EXIT /B 1
        ) ELSE (
            FOR /L %%i IN (!RANGESTART!,1,!RANGEEND!) DO (
                SET /A LASTLINE+=1
                SET LINES[!LASTLINE!]=%%i
            )
        )
    )
GOTO :EOF

REM Prints the specified line if the current line should be printed
:PRINTLINE
    SET /A CURRENTLINE+=1
    IF %CURRENTLINE%==!LINES[%INDEX%]! (
        REM We have a line to print, so do this
        ECHO !LINE!
        SET /A INDEX+=1
    )
GOTO :EOF

REM Prints usage and exits the batch file
:USAGE
    ECHO.%~n0 - Displays selected lines from a text file.
    ECHO.
    ECHO.Usage:
    ECHO.  %~n0 ^<filename^> ^<range^> ...
    ECHO.
    ECHO.  ^<filename^> - the text file from which to read
    ECHO.  ^<range^>    - the line range(s) to display.
    ECHO.
    ECHO.Example:
    ECHO.  %~n0 foo.txt 1-4 13 15 18-20
    ECHO.
    ECHO.  will display the first four lines from the file "foo.txt",
    ECHO.  the 13th and 15th as well as the lines 18 to 20.
    ECHO.
    ECHO.Line ranges are separated by comma, semicolon or space. If no range is given,
    ECHO.the entire file is displayed.
    EXIT /B 1
GOTO :EOF

The whole script could use some better error checking, examples of what not to do or where error checking is a bit wonky:

整个脚本可以使用一些更好的错误检查,不做的例子或错误检查有点不稳定的例子:

  • dl foo.txt 1-2-4 (prints lines 1-2 but no error message)
  • dl foo.txt 1-2-4(打印1-2行,但没有错误信息)

  • dl foo.txt -1 (error message that the range 1- isn't correct)
  • dl foo.txt -1(范围1-不正确的错误消息)

Other limitations:

  • Ranges must be sorted. With the current implementation there is no way to do something like dl foo.txt 7-8,1-2.
  • 范围必须排序。在目前的实现中,没有办法像dl foo.txt 7-8,1-2那样做。

  • No line may be selected twice. Something like dl foo.txt 1,2,2-8,11-15 will stop after the second line.
  • 不能选择两行。 dl foo.txt 1,2,2-8,11-15之类的东西会在第二行之后停止。

  • No support for UNIX-style line endings (U+000A)
  • 不支持UNIX样式的行结尾(U + 000A)

EDIT: Fixed an issue with files that contain parentheses.

编辑:修复了包含括号的文件的问题。