在命令提示符中显示文本文件中的第n行

6

我的文本文件包含23行(行包括:!@$:/;")

我该如何只显示第3行?还是第7行?或者第19行?

我尝试了stackoverflow上的所有命令。

示例:

setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%i in (mytext.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))

这只显示第一行。


只需从批处理文件的提示符处显示一行的需求非常罕见,您能解释一下您打算如何使用返回的行吗? - Compo
有点不相关的是,你的 if 语句是多余的;它总是会返回 true,而 1 和它是第一行没有任何关系。 - SomethingDark
文本文件有多大,最长的行有多长? - aschipfl
4个回答

8
@Compo给出了一个好的答案。这只是对其进行阐述。在脚本中不应使用别名,如GC。在命令行中,如果你感觉可以减少输入,那么可以使用别名。此外,拼写参数名称提供更多信息并有助于更快地理解。
要仅获取第三行。
GC .\mytext.txt -T 3|Select -L 1

Get-Content -Path '.\mytext.txt' -TotalCount 3 | Select-Object -Last 1

从CMD控制台(命令提示符)中获取第七行的方法如下:

PowerShell "GC .\mytext.txt -T 7|Select -L 1"

PowerShell -NoProfile "Get-Content -Path '.\mytext.txt' -TotalCount 7 | Select-Object -Last 1"

要获取第3到7行:
$FirstLine = 3
$LastLine=7
powershell -NoProfile -Command "Get-Content -Path '.\t.txt' -TotalCount $LastLine | Select-Object -Last ($LastLine - $FirstLine + 1)"

或者,在cmd.exe批处理脚本中。
SET "FIRSTLINE=3"
SET "LASTLINE=7"
powershell -NoProfile -Command ^
    "Get-Content -Path '.\t.txt' -TotalCount %LASTLINE% |" ^
        "Select-Object -Last (%LASTLINE% - %FIRSTLINE% + 1)"

当从cmd.exe批处理脚本调用PowerShell时,如在您的最后一个示例中,如果一行超过80个字符,则输出会自动在第80个位置插入换行符。我该怎么避免这种情况?在我的特定用例中,我正在将PowerShell命令的输出导管到CLIP,并且不希望在粘贴时添加换行符。 - thecommexokid
1
我在使用PowerShell 5.1.14409.1012的Windows 7 Enterprise SP1上似乎没有那个结果。 - lit

3
@echo off
setlocal
set "FILE_TO_PROCESS=%~f1"
set /a LINE_NUMBER=%~2
set /a trim=LINE_NUMBER-1

break>"%temp%\empty"&&fc "%temp%\empty" "%FILE_TO_PROCESS%" /lb  %LINE_NUMBER% /t |more +4 | findstr /B /E /V "*****"|more +%trim%
endlocal

请使用名为lineNumber.bat的批处理文件进行尝试,第一个参数是您想要处理的文件,第二个参数是行号:

call lineNumber.bat someFile.txt 5

1
哇,这是一些牛逼的命令行操作!谢谢您解决了我使用findstr的困境。我希望我能够弄清楚如何将这种魔法与获取最后一个单词相结合(也许是for /f "tokens=2" %%a in (state.txt) do set word1=%%a的某个变体)。 - deasserted
@deasserted - 你想要获取行的最后一个单词吗?虽然不能在评论中方便地回答你,但这也是可以实现的。 - npocmaka
@deasserted - 这是你所困扰的吗?https://stackoverflow.com/questions/60675577/git-parse-branch-name-from-console-output - npocmaka
是的,我使用了你提供的方法来解决那个问题。最终我采用了你的解决方案,使用set /p line=<"%temp%\empty"将其读取回来,然后使用for %%a in (!line!) do set last_phrase=%%a和EnableDelayedExpansion获取了最后一个短语。谢谢! - deasserted
为了让其他人理解这个答案的做法:break> 部分会创建一个空文件(可以是自己的一行)。它与FC(文件比较)实用程序一起使用,以裁剪 /lb LINE_NUMBER 之后的所有行。它能够工作,但其报告需要清理:因此,MORE +4 将在 LINE_NUMBER 之前裁剪 FC 结果,并使用 findstr 找到没有 ***** 的行。我不确定为什么需要最后一个 MORE,但我假设它处理了一个边角情况。如果您想保存结果,请添加 >my_filename 来存储它,然后 set /p my_line=<"my_filename " 以将其读取回来。 - deasserted

1

有几种方法可以实现这个功能。第一种选择是正常遍历for循环,并在到达所需行时退出循环。

@echo off

:: Specify which line to return
set get_line=7

:: Skip all lines before it, then print the next line and abort
set /a get_line-=1
for /F "skip=%get_line% delims=" %%A in (mytext.txt) do (
    echo %%A
    goto :end_loop
)

:end_loop

你的另一个选择是将不需要的行之前的所有行存储在临时变量中,然后显示下一行。
@echo off
setlocal enabledelayedexpansion

:: Specify which line to return
set get_line=7

:: Skip all lines before it, then print the next line and abort
set /a get_line-=2

(
    for /L %%A in (0,1,%get_line%) do set /p skip_line=
    set /p return_line=
) <file.txt

echo !return_line!

注意,第一个选项不适用于返回脚本的第一行。

0

既然你说“显示”,为什么不试试PowerShell

从PowerShell控制台开始:

GC .\mytext.txt -T 3|Select -L 1

从CMD控制台(命令提示符)

PowerShell "GC .\mytext.txt -T 7|Select -L 1"

从批处理文件中:

@(PowerShell "GC .\mytext.txt -T 19|Select -L 1"&Pause)

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