我有一个文本文件,每行都有一些单词。例如:
word1 more words
word15甚至更多的话
我想要做的是用某个单词替换第一个单词。例如;如果第一个单词是“word1”,它将被替换为“yes”,如果该行中的第一个单词是“word15”,它将被替换为“no”。
所以我需要一个循环遍历每一行并检查第一个单词并用某个单词替换它。
这是我到目前为止所做的事情,并没有做任何与我想做的事情有关的事情:
@ECHO OFF
for /F "tokens=*" %%a in (ukazi.txt) do (
set var=%%a
set new=%var:ls=dir%
set new=$
echo %new%
)
pause
我是批处理的新手,我每分钟都会越来越困惑。我会非常感谢你的帮助!
答案 0 :(得分:1)
@echo off
Setlocal EnableDelayedExpansion
for /f "tokens=*" %%i in (c:\temp\word.txt) do call :REPLACE "%%i"
:REPLACE
for /f "tokens=1,*" %%i in (%1) do (
set test=%%i
set test=!test:word15=no!
set test=!test:word1=yes!
echo !test! %%j
)
键是:
EnableDelayedExpansion
以便变量将在执行时而不是在脚本结束时展开(当您使用它时,变量将使用!variable_name进行引用!%variable_name:X=Y%
将在变量内容中用Y替换每个X字符)%1
是传递给子程序答案 1 :(得分:1)
@ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
:: set up substitution elements from replacements.txt
FOR /f "delims=" %%a IN (replacements.txt) DO SET "$%%a"
(
FOR /f "tokens=1*" %%a IN (q21450455.txt) DO CALL :rep1 %%a "%%b"
)>newfile.txt
GOTO :EOF
:rep1
IF defined $%1 (CALL SET "newword=%%$%1%%") ELSE (SET newword=%1)
ECHO %newword% %~2
GOTO :eof
不容易理解 - 所以我会解释。
首先,执行set $
命令,它将" list"任何以$
开头的变量,一个变为$alreadyset=previousvalue
格式的行。 2^>nul
确保未显示错误消息(Environment variable $ not found
)。插入符号^
)告诉cmd
重定向符>
是要执行的行的一部分,而不是FOR
。
因此,对于每一行输出(如果有的话),for /f
将该行标记为每个[系列] =
个字符(字符[set] bewteen ) delims=
和"
)是一个'令牌分隔符'。令牌1应用于元变量(在这种情况下为%%a
)。可以提名一系列令牌,然后将其应用于后续的元变量。
因此,$alreadyset=previousvalue
被标记为$alreadyset
,previousvalue
和$alreadyset
已分配给%%a
; set
命令将%%a
设置为空字符串,因此$alreadyset
设置为空字符串,因此从环境中删除。
set "var=value"
语法用于确保该行上的任何尾随空格不包含在分配的值中。空间有点难以看清......
下一个FOR /F
不使用分隔符(=
和"
之间没有字符),它会覆盖默认分隔符集,如 Space 。整条线现已分配到%%a
。所以如果replacements.txt
包含
word1=yes
word15=no
然后set
执行为set "$word1=yes"
(依此类推文件的其余部分)
最后,实际上只有一个for
循环和一个子程序。 (for...)>filename
构造在循环期间将任何ECHO
ed发送到文件中 - 即使它在子例程中echo
编辑。 >file
表示制作新文件,>>file
表示append to an existing file if there is one or make a new one.
此最终for/f
从我的测试文件q21450455.txt
word1 more words
not here word1
not at all here
word15 even more words
使用默认分隔符进行标记,将第一个标记(1)分配给%%a
,将余数(*)分配给%%b
。然后子例程rep1
被call
编辑并传递两个参数 - %%a
作为第一个(行中的第一个单词,直到第一个分隔符)和"%%b"
as第二。整个剩余部分位于%%b
- 但可能包含分隔符,因此"quoting it"
将整个剩余部分保持为一个元素。
在:rep1
中,我们会看到变量$%1
是否已定义。 %1是例程的第一个参数,因此是文件中的第一个字,因此该语句将查看$word1
是否作为环境变量存在。如果是,我们会将newword
设置为$%1
的内容,因此我们需要调用设置... = %% $%1 %%。这是一个解析技巧并执行set ... =%v $ word1%,或者不管第一个单词是什么 - 并且之前已经设置到环境中。
如果在环境中未定义$word1
,则newword
只是设置为第一个参数(即文件行中的第一个单词)。
最后,我们echo
新词和%~2
表示the second parameter, with any enclosing quotes removed
- 并将其重定向到文件。
完成工作。