我正在尝试从文本文件中打印第4行,第21-50行,这可以在Windows下以某种方式完成吗?我一直在尝试这样做:
FOR /F "usebackq tokens=1 delims=-" %G IN (%COMPUTERNAME%.txt) DO ECHO %G
这只是非常糟糕。我不能只打印一组特定的线条吗?
我需要在多台计算机上运行此脚本,理想情况下我想将其转换为变量以便与slmgr -ipk
一起使用,也许有人有更好的建议?
文本文件的内容(我想要XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
部分):
==================================================
Product Name : Windows 7 Professional
Product ID : 00371-OEM-9044632-95844
Product Key : XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
Installation Folder : C:\Windows
Service Pack : Service Pack 1
Computer Name : LIBRA
Modified Time : 6/4/2015 7:26:54 PM
==================================================
答案 0 :(得分:1)
如果您只想要"产品密钥"你可以试试
type %COMPUTERNAME%.txt|find /i "Product Key"
或
for /f "tokens=2 delims=:" %%# in (' type %COMPUTERNAME%.txt^|find /i "Product Key"') do echo %%#
答案 1 :(得分:1)
对于手头的任务,npocmaka's answer是最合适的方法,因为它不会坚持要从文件中提取字符串的固定位置。
但是,我想提供一个坚持某个位置的变体。
以下代码提取放置在文件list.txt
的第4行的第21行到第50列的字符串(结果被回显(包含在""
中)并存储在变量LINE_TXT
中(不带""
):
@echo off
for /F "tokens=1,* delims=:" %%L in (
'findstr /N /R ".*" "list.txt"'
) do (
if %%L equ 4 (
set "LINE_TXT=%%M"
goto :NEXT
)
)
:NEXT
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
goto :NEXT
命令终止给定行的for /F
循环;这不是强制性的,但会提高大型文件的性能(只要给定的行号非常小)。
为了更灵活,可以使用以下代码(在初始set
块中定义字符串位置):
@echo off
rem Define the string position here:
set FILE_TXT="list.txt"
set LINE_NUM=4
set COL_FROM=21
set COL_UPTO=50
setlocal EnableDelayedExpansion
set /A COL_UPTO-=COL_FROM
set /A COL_FROM-=1
for /F "tokens=1,* delims=:" %%L in (
'findstr /N /R ".*" %FILE_TXT%'
) do (
if %%L equ %LINE_NUM% (
set "LINE_TXT=%%M"
if defined LINE_TXT (
set "LINE_TXT=!LINE_TXT:~%COL_FROM%,%COL_UPTO%!"
)
goto :NEXT
)
)
:NEXT
endlocal & set "LINE_TXT=%LINE_TXT%"
echo."%LINE_TXT%"
以上两个代码片段都依赖于findstr /N /R ".*"
的输出,它返回与正则表达式.*
匹配的每一行,表示零个或多个字符,而每个行实际上都是如此在文件中;但是,开关/N
定义为每行添加其行号,我将其提取并与最初定义的行进行比较。
这是另一种变体,它使用for /F
直接遍历给定文本文件的内容(行),而不使用findstr
:
@echo off
for /F "usebackq skip=3 eol== delims=" %%L in (
"list.txt"
) do (
set "LINE_TXT=%%L"
goto :NEXT
)
:NEXT
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
此方法具有更好的性能,因为有skip
选项跳过解析并迭代感兴趣的行(4)之前的所有行(1到3),而不是{{1变种。
但是,有一个缺点:
findstring
具有for /F
选项,用于定义解释为行注释的字符(默认为eol
);只要;
没有定义分隔符(选项字符串中的最后一个位置),就无法关闭此选项,这在此处必须按原样返回该行;所以你必须找到一个在任何一行中都不是第一个的字符(我在这里定义了delims=
,因为你的示例文本文件仅使用它作为页眉/页脚字符。)
要从第1行提取字符串,请删除=
选项,因为skip
会导致语法错误。
请注意,此处需要skip=0
;否则,将提取文件的最后一行(非空)。
虽然goto :NEXT
不会迭代文件中的任何空行,但这里没有问题,因为for /F
选项不会检查行内容并跳过空行。
最后,这是使用skip
的另一种方法,其中不进行文本解析。但是,此处需要一个临时文件将所需行的文本传递给变量more +3
:
LINE_TXT
此方法避免了@echo off
set LINE_TXT=
more +3 "list.txt" > "list.tmp"
set /P LINE_TXT= < "list.tmp"
del /Q "list.tmp"
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
exit /B 0
,因此避免了上述解决方案中提到的不需要的for /F
选项的问题。但这并没有正确处理标签,因为eol
用空格替换它们(默认情况下有8个缩进空格,可由more
开关配置,其中/Tn
是空格数。)