2015-01-04 35 views
0

我有一個文件批量替換第2個字符

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

有一個名爲'sed'的工具,另一個名爲'awk',都可以做你想做的事情。 – MondKin

+0

另外,考慮顯示你已經嘗試。 – MondKin

+0

以及我需要在Windows批處理中運行此操作。在Linux中,我用sed做了它,並且將新條目追加到文件末尾。 –

回答

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 
0

你的回答不能滿足您的要求「開頭爲」。聽起來像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 ,用雙引號取代單引號,以防止cmd將克拉解釋爲轉義字符。)

如果您不希望使用GnuWin32 sed,那麼意識到Windows批處理中的正則表達式支持很弱。有findstr,但它只支持最基本的正則表達式匹配,並沒有做替換。 (這就像一個非常虛弱grep

如果你想有一個解決方案,您可以在.bat文件堅持並運行它,那麼我建議一個批次/ JScript的混合腳本,這樣的事情:

@if (@[email protected]) @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替換上面的正則表達式,以查找(但不包括)數字作爲該行的第三個字符。

你在JavaScript有多好?如果你對JavaScript感到滿意,你會(希望)發現JScript易於遵循並根據需要進行維護。

0

這是一個微不足道的問題,如果你可以在一次完成所有的替換。使用JREPL.BAT輕鬆完成 - 一個混合的JScript /批處理實用程序,它執行正則表達式搜索並替換文本數據。 JREPL.BAT是純粹的腳本,可以在任何Windows XP機器上運行。我使用/T選項將一系列搜索詞翻譯爲一系列替換詞。 /I選項忽略大小寫,而/B選項強制每個術語僅匹配一行的開頭(比每個術語包含^更容易)。/F選項指定源文件,而具有-值的/O選項將導致輸出替換原始文件。

jrepl "MD CL CM" "MADR CYLR CLMR" /i /t " " /b /f test.txt /o - 

如果在批處理腳本中使用,那麼您必須使用CALL,因爲JREPL也是批處理腳本。

UPDATE

如果是不應該行,如果他們已經與目標字符串中的一個開始被改變,那麼只需要一個小的變化:

jrepl "MD CL(?!MR) CM" "MADR CYLR CLMR" /i /t " " /b /f test.txt 
+0

'jrepl.bat'能否排除替換'CLMX' /'CLMR'?根據主要問題的頂部代碼塊,示例文件可能已經包含這些字符串,並且不需要更改。也許在你的解決方案中添加'cylrmx'和'cylrmr'的替代品以便打出錯誤的匹配。 – rojo

+0

@rojo - 沒問題。我對這個問題有不同的解釋。我認爲當一個目標字符串匹配不同的搜索字符串時,OP在進行搜索/替換時遇到問題,因此可能會修改相同的兩行。我原來的答案避免了這個問題。我添加了第二種解決方案,如果它已經與某個目標字符串匹配,則不會更改該行。 – dbenham

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