2014-01-30 72 views
0

我有一个文本文件,每行都有一定的文字。例如:逐行读取文件并替换某些文字

WORD1更多的话

word15更加字

我想要做的就是用某个词来替换第一个字。例如;如果第一个单词是“word1”,它将被替换为“是”,并且如果该行中的第一个单词是“word15”,它将被替换为“否”。

因此,我需要一个循环遍历每一行,并检查第一个单词并将其替换为某个单词。

这是我迄今为止,并没有做任何远程接近我想要做的:

@ECHO OFF 
for /F "tokens=*" %%a in (ukazi.txt) do (
set var=%%a 
set new=%var:ls=dir% 
set new=$ 
echo %new% 
) 
pause 

我是新来的一批,我感到困惑越来越多的每分钟。我会很感激的帮助!

回答

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,这样的变量将扩大在执行时间,而不是在脚本的末尾(当你使用这个变量时,变量将被引用using!variable_name!
  • 使用'in-place'变量替换(即:%variable_name:X=Y%将在变量内容中用Y代替每个X字符)
  • %1是第一个参数传递给子程序
+0

它的工作原理!谢谢!但我想了解一些行话。在第二个FOR中有什么%1? – Guy

+0

@Matthew我已经更新了我的答案 –

+0

谢谢:)哦,还有一件事。为什么在第二个“令牌= 1,*”?如果它只是“tokens =”*“,那么它会不一样吗? – Guy

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 $命令,该命令将“列出”开始的所有变量$,其中一个格式为$alreadyset=previousvalue2^>nul确保没有显示错误消息(Environment variable $ not found)。插入符号(^)告诉cmd重定向器>是要执行的行的一部分,而不是FOR

因此,对于输出的每一行(如果有的话),for /f tokenises线,使得每个[系列] =字符(字符[组] bewteendelims=")是一个“令牌分隔符” 。令牌1应用于元变量(在这种情况下为%%a)。可以提出一系列令牌,然后将其应用于后续的元变量。

所以,$alreadyset=previousvalue被标记化到$alreadysetpreviousvalue$alreadyset分配给%%a; set命令将%%a设置为空字符串,因此$alreadyset被设置为空字符串并因此从环境中删除。

set "var=value"语法用于确保行中的任何尾随空格都包含在分配的值中的而不是。空间是有点难以看到...

FOR /F不使用分隔符(="之间没有字符)将覆盖默认的分隔符设置像空间。整行现在被分配到%%a。因此,如果replacements.txt包含

word1=yes 
word15=no 

那么set作为set "$word1=yes"执行(等对文件的其余部分)

最后,真的只是一个for循环和子程序。 (for...)>filename构造将循环期间编辑的任何内容发送到文件中 - 即使它在子例程中编辑了echo也是如此。 >file手段使一个新的文件,>>file将意味着append to an existing file if there is one or make a new one.

这最终for/f读取我的测试文件ECH线,q21450455.txt

word1 more words 
not here word1 
not at all here 
word15 even more words 

tokenising使用默认的分隔符,分配第一令牌(1)%%a和其余(*)至%%b。然后子程序rep1call ed,并且通过两个参数 - %%a作为第一个(从行的第一个字,直到第一个分隔符)和"%%b"作为第二个。整个休息的线在%%b - 但可能包含分隔符,所以"quoting it"保留整个休息线作为一个元素在一起。

:rep1中,我们看到是否定义了变量$%1。 %1是例程的第一个参数,因此是文件中的第一个单词,因此该语句将查看$word1是否作为环境变量存在。如果是这样,我们将newword设置为$%1的内容,因此我们需要调用 set ... = %% $%1 %%。这是一个解析技巧,并且执行set ... =%v $ word1%,或者第一个词是什么 - 并且是早期设置到环境中的。

如果在环境中未定义$word1,则简单地将newword设置为第一个参数(即文件行中的第一个字)。

最后,我们echo的新词和%~2这意味着the second parameter, with any enclosing quotes removed - 这是重定向到文件。

工作完成。

+0

我并不需要像这样复杂的事情,因为我是一个完整的初学者,但非常感谢!在阅读这本书时,我肯定会学到很多新东西:) – Guy