逐行读取文件并替换某些单词

时间:2014-01-30 07:40:17

标签: batch-file

我有一个文本文件,每行都有一些单词。例如:

  

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

我是批处理的新手,我每分钟都会越来越困惑。我会非常感谢你的帮助!

2 个答案:

答案 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被标记为$alreadysetpreviousvalue$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

中读取ech行
word1 more words
not here word1
not at all here
word15 even more words

使用默认分隔符进行标记,将第一个标记(1)分配给%%a,将余数(*)分配给%%b。然后子例程rep1call编辑并传递两个参数 - %%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 - 并将其重定向到文件。

完成工作。