So ersetzen Sie Teilzeichenfolgen in Windows-Batchdateien

74

Kann mir jemand sagen, wie man eine Batch-Datei in Windows verwendet ... wie man aus einer Datei liest und string = bathaus einer Datei mit = bath Abath Bbath XYZbathABCdurch string ersetzt, helloso dass die Ausgabe wie folgt isthello Ahello Bhello XYZhelloABC

EnoshBansode
quelle

Antworten:

103

Erweitern von Andriy M , und ja, Sie können dies aus einer Datei heraus tun, auch aus einer mit mehreren Zeilen

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "OUTTEXTFILE=test_out.txt"
set "SEARCHTEXT=bath"
set "REPLACETEXT=hello"

for /f "delims=" %%A in ('type "%INTEXTFILE%"') do (
    set "string=%%A"
    set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
    echo !modified!>>"%OUTTEXTFILE%"
)

del "%INTEXTFILE%"
rename "%OUTTEXTFILE%" "%INTEXTFILE%"
endlocal

BEARBEITEN

Vielen Dank, David Nelson. Ich habe das Skript aktualisiert, damit es nicht mehr die fest codierten Werte enthält.

eine Wohnung
quelle
1
Es ist schön und funktioniert, aber aus irgendeinem Grund werden leere Zeilen entfernt. Gonzalezeas Antwort unter dem folgenden Link behebt das Problem des Entfernens
user280109
1
Einige Informationen für Leser, die über die Verwendung des Codes nachdenken: FOR ignoriert leere Zeilen und mit diesem Code auch Zeilen, die mit beginnen, ;da dies die Standardoption für ist eol. Zeilen mit einer oder mehreren !werden mit diesem Code nicht korrekt verarbeitet, da für diesen Code eine aktivierte verzögerte Erweiterung erforderlich ist. ECHO- Ausgaben echo is off.im Fall einer Umgebungsvariablen werden modifiedgelöscht, da die Ersetzungszeichenfolge eine leere Zeichenfolge ist und die Suchzeichenfolge mit der gesamten Zeile übereinstimmt. Die Suchzeichenfolge darf kein Gleichheitszeichen enthalten, da sie =im Substitutionsausdruck eine besondere Bedeutung hat.
Mofi
Ist dieser Code sehr unterschiedlich, wenn ich zwei separate Zeichenfolgen wie bei einer anderen ändern muss set "modified1=...?
Zygimantus
Wow, das scheint für so eine einfache Sache übertrieben zu sein.
Sören
44
SET string=bath Abath Bbath XYZbathABC
SET modified=%string:bath=hello%
ECHO %string%
ECHO %modified%

BEARBEITEN

Ich habe zunächst nicht gesehen, dass vor dem Ersetzen die Zeichenfolge aus einer Datei gelesen werden soll.

Nun, mit einer Batch-Datei haben Sie nicht viel Möglichkeiten, an Dateien zu arbeiten. In diesem speziellen Fall müssten Sie eine Zeile lesen, das Ersetzen durchführen, dann die geänderte Zeile ausgeben und dann ... Was dann? Wenn Sie alle Vorkommen von 'bath' in der gesamten Datei ersetzen müssen, müssen Sie eine Schleife verwenden:

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
FOR /F %%L IN (file.txt) DO (
  SET "line=%%L"
  SETLOCAL ENABLEDELAYEDEXPANSION
  ECHO !line:bath=hello!
  ENDLOCAL
)
ENDLOCAL

Sie können einer Datei eine Umleitung hinzufügen:

  ECHO !line:bath=hello!>>file2.txt

Oder Sie können die Umleitung auf die Batchdatei anwenden. Es muss eine andere Datei sein.

BEARBEITEN 2

Hinzugefügt richtige Hin- und Herschalten der verzögerten Expansion für die korrekte Verarbeitung von einigen Zeichen , die spezielle Bedeutung mit Batch - Skript - Syntax hat, wie !, ^et al. (Danke, jeb !)

Andriy M.
quelle
OK, zumindest für eine Zeichenfolge ist dies mit Windows-Batch-Funktionen möglich (nicht kompatibel mit DOS-Batch- oder älteren Windows-Versionen). Aber ich wäre überrascht, wenn dies für eine Datei funktioniert (insbesondere für eine Datei mit mehreren Zeilen).
Schnaader
1
@schnaader: Es ist möglich, versuchen Sie einen Blick auf Batch FindAndReplace
jeb
@jeb: OK, also ist es zumindest möglich, danke für den Link. Wie auch immer, hier gelten sowohl "sehr kompliziert" als auch "inkompatibel" aus meiner Antwort.
Schnaader
1
@schnaader: Im Allgemeinen ist es nicht so elegant wie einige andere Skript-Tools. Ich vermute, dass sie anfangs Batch- Dateien genannt wurden, was einfach Batch-Ausführung (von Befehlen) bedeutet. Aber da kann ich mich irren. Wie auch immer, was ist mit cscriptund PowerShellda zu sein, ich denke manchmal, dass sie Batch-Dateien komplett verschrottet hätten, wenn nicht die wahrscheinlich enorme Anzahl von Skripten gewesen wäre, die im gesamten Windows-Bereich noch verwendet werden.
Andriy M
@Andriy M: Es kann verbessert werden, um mit !und ^im Inhalt sicher zu sein, indem die verzögerte Erweiterung ein-
jeb
13

Um das Überspringen von Leerzeilen zu vermeiden (Lesbarkeit in der conf-Datei angeben), kombiniere ich eine flache und eine jeb-Antwort ( hier ) auf Folgendes :

@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"findstr /n ^^ %INTEXTFILE%"') do (
   SET string=%%A
   for /f "delims=: tokens=1,*" %%a in ("!string!") do set "string=%%b"
   if  "!string!" == "" (
       echo.>>%OUTTEXTFILE%
   ) else (
      SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
      echo !modified! >> %OUTTEXTFILE%
  )
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
gonzalezea
quelle
Möglicherweise möchten Sie auch die richtige Codepage festlegen, um Probleme mit Nicht-Ansi-Zeichen in der Textdatei zu vermeiden: z. B. chcp 65001für UTF8: Siehe Echo UTF-8-Zeichen im Windows-Stapel
TmTron
4

Um Probleme mit dem Batch-Parser (z. B. Ausrufezeichen) zu vermeiden, lesen Sie Problem beim Suchen und Ersetzen der Batch-Datei .

Nach der Änderung des Skripts von aflat werden Sonderzeichen wie Ausrufezeichen eingefügt .

@echo off
setlocal DisableDelayedExpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"type %INTEXTFILE%"') do (
    SET string=%%A
    setlocal EnableDelayedExpansion
    SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!

    >> %OUTTEXTFILE% echo(!modified!
    endlocal
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
Eichhorn
quelle
0

Ich habe eine Funktion dafür erstellt, Sie rufen sie nur in einem Stapelverarbeitungsprogramm auf, wenn Sie mehr Code benötigen.

Die Arbeitsweise ist im Grunde die gleiche wie bei den anderen, da dies der beste Weg ist, dies zu tun.
Hier ist der Link, wo ich diese Funktion habe

Anic17
quelle
-1

Um das Überspringen von Leerzeilen zu vermeiden, ersetzen Sie diese einfach:

echo !modified! >> %OUTTEXTFILE%

mit diesem:

echo.!modified! >> %OUTTEXTFILE%
Fernando Adrian
quelle
2
Dies ist keine Antwort auf die Frage
jeb
-7

Wenn Sie Ruby für Windows haben ,

C:\>more file
bath Abath Bbath XYZbathABC

C:\>ruby -pne "$_.gsub!(/bath/,\"hello\")" file
hello Ahello Bhello XYZhelloABC
kurumi
quelle