我找到了杰布(Jeb)的答案,可以通过在每行的开头添加数字:将文件复制到另一个包含空行的文件
(
set taglinelinks=one two three
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ overview.md"`) do (
set "var=%%a"
if "%var:~0,2%" == "5:" (echo %taglinelinks%)
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
)
) > new.txt
我在顶部添加了用于测试的变量,并添加了“ if”行。没有“ if”行,它可以正常工作,但是我看不到该行有任何问题。我正在检查行数是否为5,如果是,则将变量回显到文件,然后继续。我应该在if语句中使用else命令,但是现在我无法确定要在其中放置什么以防止其余代码跳过第5行的原始内容。
答案 0 :(得分:2)
在此答案中,我坚持我们的原始代码,并专注于缺陷。基本上,我喜欢这种方法(当然,错误已得到纠正),因为它甚至可以正确处理以冒号:
开头的行,并且文本中出现!
也不存在任何问题文件,因为切换了延迟扩展。
无论如何,首先,我想显示经过修改的有效代码:
@echo off
setlocal DisableDelayedExpansion
set "taglinelinks=one two three"
> "new.txt" (
for /F "delims=" %%a in ('findstr /N "^" "overview.md"') do (
set "var=%%a"
setlocal EnableDelayedExpansion
if "!var:~,2!" == "5:" (
echo(!taglinelinks!
) else (
echo(!var:*:=!
)
endlocal
)
)
endlocal
这就是我所纠正的:
if
子句必须处于启用了延迟扩展的块中,因此我将其向下移动了一行,并将%
更改为!
; else
子句,以使其包含for /F
循环主体中的其余代码部分endlocal
,因此您无法遇到setlocal
的嵌套限制,并且set "var=%%a"
命令行实际上出现在禁用了延迟扩展的代码部分中,这对于不会引起文件中出现!
的麻烦; 以下是一些细微的外观变化:
@echo off
,我在顶部添加了new.txt
; setlocal
命令移到顶部以首先禁用延迟扩展,因此!
甚至可以安全地用于重定向的文件名和第一个set
命令中行(因为我们可能不知道延迟扩展是先禁用还是启用); set
来分配变量taglinelinks
以使其安全;然后我将这行代码移到了重定向块之外,只是变得更加明显; usebackq
选项不是必需的,因此我将其删除并使用了单引号''
(但这里只是个问题); findstr
命令行显得有些奇怪,尤其是转义的插入符号^^
,因此我更改了引号,以便对搜索字符串以及文件路径进行引号,因此不会进行此类转义不再需要,文件名甚至可以包含空格或其他特殊字符; taglinelinks
值的行不在启用延迟扩展的块中;这允许变量甚至包含特殊字符; set "var=!var:*:=!"
并不是必须的,因此我将其删除并立即回显了被截断的字符串; if
/ else
块修改了代码缩进,以提高可读性; > "new.txt"
移动到了外部括号块的前面,以使其更加可见(但这在这里只是个问题),并且在文件名两边加上了双引号,因此它甚至可能包含空格或其他特殊字符; endlocal
的显式setlocal
命令; 我在脚本中仍然不喜欢一件事,即不灵活的方式来标识当前行的编号,因为它当前仅适用于小于10
的编号,而无需对代码进行一点改动。
这是一种灵活指定要替换的行号的方法:
@echo off
setlocal DisableDelayedExpansion
set "taglinelinks=one two three"
set "linenumber=5"
> "new.txt" (
for /F "delims=" %%a in ('findstr /N "^" "overview.md"') do (
set "var=%%a"
setlocal EnableDelayedExpansion
set /A "num=var"
if !num! equ !linenumber! (
echo(!taglinelinks!
) else (
echo(!var:*:=!
)
endlocal
)
)
endlocal
这就是我所做的:
linenumber
定义了一个变量(常量)5
;认为linenumber
不能包含前导零,以便以后不将其解释为八进制整数(由if
表示); set /A "num=var"
,该循环利用了set /A
的隐式变量扩展,这意味着该行字符串从左到右扫描到第一个非数字字符 1 ,然后将此字符串转换为整数,最后分配给num
;这意味着该文件包含少于2 31 行; if
子句更改为if !num! equ !linenumber!
,由于两个表达式都是整数,因此由于equ
而执行数字比较。因此,这不再取决于行号的位数;在这里我也可以使用%linenumber%
,因为代码块中的变量没有更改,但是我决定使用!linenumber!
来覆盖该变量初始化错误的情况(尤其是当它为空或包含拼写错误引起的特殊字符); 1)实际上忽略前导的 SPACE 和 TAB 。接下来可能会出现单个+
或-
符号。然后使用直到下一个非数字数字的所有内容将字符串转换为带符号的32位整数。如果结果不能如此表示,它将被强制。
答案 1 :(得分:1)
您可以这样尝试:
@Echo Off
Set "taglinelinks=one two three"
( For /F "Tokens=1*Delims=:" %%A in ('Findstr /N "^" "overview.md"')Do (
If %%A NEq 5 (Echo=%%B)Else Echo %taglinelinks%
)
)>"new.txt"