我有一个文件的例子
CM2345
CLMX2345
CLMR5254
CYLR5121
CL2135
MADX5321
MD2145
MADR1234
CYLX1234
我需要做的是替换以
开头的文件中的所有行md -> MADR
cl -> CYLR
cm -> CLMR
当替换cl时会出现问题,因为clmx和clmr也以cl开头。
这就是我在linux中做到的,现在我需要在windows批处理
for file in *.db; do
while read p; do
if [[ "$p" == CL* ]] && [[ "$p" != CLM* ]] ;
then
r=$(echo $p | sed 's/..//')
echo $r > c.l
while read line
do
echo "CYLR$line" >> $file
done <c.l
fi
done <"$file"
wait
done
谢谢!
答案 0 :(得分:0)
好的我不知道如何检查它是以clmx还是clmr开头,而不是替换这些行的cl,我实际上没有时间。我做的是一个技巧,我首先替换所有条目,然后修复错误的
(Get-Content .\t.txt) | ForEach-Object { $_ -replace "cl", "cylr" } | Set-Content .\t.txt
(Get-Content .\t.txt) | ForEach-Object { $_ -replace "md", "madr" } | Set-Content .\t.txt
(Get-Content .\t.txt) | ForEach-Object { $_ -replace "cm", "clmr" } | Set-Content .\t.txt
(Get-Content .\t.txt) | ForEach-Object { $_ -replace "cylrMX", "clmx" } | Set-Content .\t.txt
(Get-Content .\t.txt) | ForEach-Object { $_ -replace "cylrMr", "clmr" } | Set-Content .\t.txt
答案 1 :(得分:0)
您的回答并不符合以&#34;开头的行?需求。听起来像sed
真的是这项工作的最佳工具。您可以获取GnuWin32 sed.exe
并使用它来执行替换。顺便说一下,你的问题中的shell脚本可以通过允许sed
内联读取和修改你的文件来缩短为单行:
sed -i -r -e '/^CLM/! s/^CL/CYLK/ig' -e 's/^CM/CLMR/ig' -e 's/^MD/MADX/ig' *.db
(如果您想在Windows中使用该行,请将单引号替换为double,以防止cmd
将克拉解释为转义字符。)
如果您不想使用GnuWin32 sed
,那么意识到Windows批处理中的正则表达式支持相当薄弱。有findstr
,但它只支持最基本的正则表达式匹配,并且不进行替换。 (它就像一个非常弱的grep
。)
如果你想要一个解决方案,你可以坚持使用.bat
文件并运行它,那么我建议使用批处理/ JScript混合脚本,如下所示:
@if (@a==@b) @end /* begin JScript hybrid multiline comment
:: batch portion
@echo off
setlocal
for %%I in (*.db) do (
cscript /nologo /e:JScript "%~f0" "%%~I"
)
goto :EOF
:: end batch / begin JScript */
var fso = new ActiveXObject('scripting.filesystemobject'),
forReading = 1,
dbFile = WSH.Arguments(0),
oldFile = dbFile.replace(/\.\w+$/, '.old');
fso.MoveFile(dbFile, oldFile);
var reader = fso.OpenTextFile(oldFile, forReading),
writer = fso.CreateTextFile(dbFile);
while (!reader.AtEndOfStream) {
var line = reader.ReadLine();
writer.WriteLine(line.replace(
/^(md|cl|cm)(?!mx|mr)/ig,
function(match, $1) {
return {
md: 'MADR',
cl: 'CYLR',
cm: 'CLMR'
}[$1.toLowerCase()];
} // end function
)); // end replace() and WriteLine()
} // end while
reader.Close();
writer.Close();
// uncomment if you don't wish to keep backup as .old
// fso.DeleteFile(oldFile);
如果要替换的字符串总是两个字母后跟数字,那么我建议用/^(md|cl|cm)(?=\d)/ig
替换上面的正则表达式,以期望(但不包括)一个数字作为该行的第3个字符
你对JavaScript有多好?如果您对JavaScript感到满意,那么您(希望)会发现JScript易于遵循和维护。
答案 2 :(得分:0)
如果您可以一次完成所有替换,这是一个微不足道的问题。使用JREPL.BAT轻松完成 - 一种混合JScript /批处理实用程序,可执行正则表达式搜索并替换文本数据。 JREPL.BAT是纯脚本,可以在XP之后的任何Windows机器上本机运行。
我使用/T
选项将一系列搜索字词转换为一系列替换字词。 /I
选项会忽略大小写,而/B
选项会强制每个字词仅匹配一行的开头(比每个字词包含^
更容易)。 /F
选项指定源文件,带/O
值的-
选项会导致输出替换原始文件。
jrepl "MD CL CM" "MADR CYLR CLMR" /i /t " " /b /f test.txt /o -
如果在批处理脚本中使用,则必须使用CALL,因为JREPL也是批处理脚本。
<强>更新强>
如果行已经以其中一个目标字符串开头,则不应该更改行,那么只需要进行微小的更改:
jrepl "MD CL(?!MR) CM" "MADR CYLR CLMR" /i /t " " /b /f test.txt
答案 3 :(得分:0)
这是一个纯粹的批处理文件程序,可以解决您所说的问题:
@echo off
setlocal EnableDelayedExpansion
rem Define the set of replacements:
for %%a in ("md=MADR" "cl=CYLR" "cm=CLMR") do for /F "tokens=1,2 delims==" %%b in (%%a) do set "replace[%%b]=%%c"
rem Define the values to preserve:
for %%a in (CLMX CLMR) do set preserve[%%a]=1
(for /F "delims=" %%a in (input.txt) do (
set "line=%%a"
for /F "tokens=1,2" %%b in ("!line:~0,4! !line:~0,2!") do (
if not defined preserve[%%b] if defined replace[%%c] set "line=!replace[%%c]!!line:~2!"
)
echo !line!
)) > output.txt
输出示例:
CLMR2345
CLMX2345
CLMR5254
CYLR5121
CYLR2135
MADX5321
MADR2145
MADR1234
CYLX1234