从文本文件中提取第n行(n为命令行参数)并输出

4

我有一个简单的文本文件,其中包含数字,例如:

12345
45678
34567
89101

我需要一个批处理程序,它可以返回该文件的第n行。n应该从命令行参数中获取。
由于我对批处理脚本非常陌生,在此先提前感谢您的帮助。

这是Windows还是Unix? - ColWhi
7个回答

6
要从第n行开始获取文件,您可以使用more +n命令(对于第一行,n=0)。
要分割文件的其余部分,可以使用FOR /F循环。
即使在第n行之前有空行也可以正常运行。
可能需要将EOL设置为未使用的字符或换行符(默认为“;”)。
set "lineNr=%1"
set /a lineNr-=1
for /f "usebackq delims=" %%a in (`more +%lineNr% text.txt`) DO (
  echo %%a
  goto :leave
)
:leave

@jep,如何将eol设置为换行符? - aschipfl

1

你可以使用批处理文件扩展名。

token.bat

 @echo off

 setlocal ENABLEDELAYEDEXPANSION
 set l=%1
 set c=0
 for /f "delims=" %%1 in ('type foo.txt') do (
   set /a c+=1 && if "!c!" equ "%l%" echo %%1%
 )

如果你有以下这样的文件,

foo.txt

 AAAA
 BBBB
 CCCC
 DDDD

并且像下面这样指定行号

 token 3

你将获得

CCCC


+1,你比我快,但是为什么要将分隔符设置为\n - jeb
抱歉,我误删了“\n”。谢谢您的提醒。 - mattn
顺便提一下,你的版本会从输出行中删除所有 ! ,有时也会删除 ^ - jeb
嗯,我不理解“为什么会发生这种情况”。 - mattn
由于启用了延迟扩展,因此已删除 !,只有在禁用扩展时,您才能安全地访问 %%1。请参见从文件名中删除特殊字符的脚本 - jeb

0
你可以使用带有“skip”参数的FOR /F
@ECHO OFF
SET skip=%1
SET /A skip-=1
IF %skip% LSS 0 GOTO out
IF %skip% GTR 0 SET params="skip=%skip%"
FOR /F %params% %%L IN (filename) DO (SET "line=%%L"& GOTO out)
:out
ECHO %line%

skip 参数表示 FOR /F 循环必须在开头跳过指定数量的行。该参数仅在您指定大于 1 的行号时应用。如果您指定小于 1 或非数字的数字,则脚本将输出空字符串。


0
基于Amit的答案,我制作了一个名为snip.cmd的实用程序。
使用方法:snip 文件名 行号 起始字符 结束字符 例如:

foo.txt

    //
    // File Checksum Integrity Verifier version 2.05.
    //
    77752e4c91ba96dcc6c2bb4bdcdbdec5 c:\users\lapinot\desktop\token.bat

snip foo.txt 3 0 33 将产生 77752e4c91ba96dcc6c2bb4bdcdbdec5

这是我的 snipe.cmd 代码(您可以通过将 snip.cmd 复制到 c:\Windows\System32 来将 snipe 添加到命令行):

    @echo off
    :: USAGE
    :: snip <file> [Line - Starts at 0] [First Column - Start Count at 0] [Last Colum]


    set file=%1
    set line=%2
    set char1=%3
    set char2=%4

    for /f "usebackq delims=" %%a in (`more +%line% %file%`) DO (set findstringline=%%a& goto :nextstep)

    :nextstep
    echo echo %%findstringline:^~%char1%,%char2%%% > %temp%\result.bat
    %temp%\result.bat
    del %temp%\result.bat
    :EOF
    exit /b

0

查找第L行中第N到第M个字符 --- 查找标签的示例


@echo off

REM Next line = Set command value to a file  OR  Just Choose Your File By Skipping The Line
vol E: > %temp%\justtmp.txt
REM  Vol E:  = Find Volume Lable Of Drive E

REM  Next Line to choose line line no. +0 = line no. 1 
for /f "usebackq delims=" %%a in (`more +0 %temp%\justtmp.txt`) DO (set findstringline=%%a& goto :nextstep)

:nextstep

REM  Next line to read nth to mth Character  here 22th Character to 40th Character
set result=%findstringline:~22,40%

echo %result%
pause
exit /b

保存为 find label.cmd

结果将是您的 E 盘标签

享受吧


0
+1 给 Jeb 的解决方案...我没有意识到你可以使用 more 命令来跳过这样的行!
这里是我用于从文件(或另一个程序的多行输出)获取特定行的替代方法:
@echo off
for /f "tokens=1* delims=:" %%a in ('findstr /n .* "C:\SomeFile.txt"') do (
  if "%%a" equ "%1" echo.%%b
)

我使用findstr /n .* "路径\文件名.ext"添加行号,并确保for循环不会跳过任何空行。

然后,我设置"tokens=1* delims=:"来将行号与行内容分开。

最后,我将当前行号(%%a)与由%1参数指定的行进行比较,并在匹配时回显行内容(%%b)。


-3

echo "输入行号.."; read i; awk 'NR==$i' <文件名>;


3
这个问题被标记为 [batch-file],所以你的解决方案不适合。 - jeb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接