How can you find and replace text in a file using the Windows command-line environment?

Note – Be sure to see the update at the end of this answer for a link to the superior JREPL.BAT that supersedes REPL.BAT
JREPL.BAT 7.0 and above natively supports unicode (UTF-16LE) via the /UTF option, as well as any other character set, including UTF-8, via ADO!!!!


I have written a small hybrid JScript/batch utility called REPL.BAT that is very convenient for modifying ASCII (or extended ASCII) files via the command line or a batch file. The purely native script does not require installation of any 3rd party executeable, and it works on any modern Windows version from XP onward. It is also very fast, especially when compared to pure batch solutions.

REPL.BAT simply reads stdin, performs a JScript regex search and replace, and writes the result to stdout.

Here is a trivial example of how to replace foo with bar in test.txt, assuming REPL.BAT is in your current folder, or better yet, somewhere within your PATH:

type test.txt|repl "foo" "bar" >test.txt.new
move /y test.txt.new test.txt

The JScript regex capabilities make it very powerful, especially the ability of the replacement text to reference captured substrings from the search text.

I’ve included a number of options in the utility that make it quite powerful. For example, combining the M and X options enable modification of binary files! The M Multi-line option allows searches across multiple lines. The X eXtended substitution pattern option provides escape sequences that enable inclusion of any binary value in the replacement text.

The entire utility could have been written as pure JScript, but the hybrid batch file eliminates the need to explicitly specify CSCRIPT every time you want to use the utility.

Here is the REPL.BAT script. Full documentation is embedded within the script.

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::************ Documentation ***********
::REPL.BAT version 6.2
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?[REGEX|REPLACE]
:::REPL  /V
:::
:::  Performs a global regular expression search and replace operation on
:::  each line of input from stdin and prints the result to stdout.
:::
:::  Each parameter may be optionally enclosed by double quotes. The double
:::  quotes are not considered part of the argument. The quotes are required
:::  if the parameter contains a batch token delimiter like space, tab, comma,
:::  semicolon. The quotes should also be used if the argument contains a
:::  batch special character like &, |, etc. so that the special character
:::  does not need to be escaped with ^.
:::
:::  If called with a single argument of /?, then prints help documentation
:::  to stdout. If a single argument of /?REGEX, then opens up Microsoft's
:::  JScript regular expression documentation within your browser. If a single
:::  argument of /?REPLACE, then opens up Microsoft's JScript REPLACE
:::  documentation within your browser.
:::
:::  If called with a single argument of /V, case insensitive, then prints
:::  the version of REPL.BAT.
:::
:::  Search  - By default, this is a case sensitive JScript (ECMA) regular
:::            expression expressed as a string.
:::
:::            JScript regex syntax documentation is available at
:::            http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx
:::
:::  Replace - By default, this is the string to be used as a replacement for
:::            each found search expression. Full support is provided for
:::            substituion patterns available to the JScript replace method.
:::
:::            For example, $& represents the portion of the source that matched
:::            the entire search pattern, $1 represents the first captured
:::            submatch, $2 the second captured submatch, etc. A $ literal
:::            can be escaped as $$.
:::
:::            An empty replacement string must be represented as "".
:::
:::            Replace substitution pattern syntax is fully documented at
:::            http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx
:::
:::  Options - An optional string of characters used to alter the behavior
:::            of REPL. The option characters are case insensitive, and may
:::            appear in any order.
:::
:::            A - Only print altered lines. Unaltered lines are discarded.
:::                If the S options is present, then prints the result only if
:::                there was a change anywhere in the string. The A option is
:::                incompatible with the M option unless the S option is present.
:::
:::            B - The Search must match the beginning of a line.
:::                Mostly used with literal searches.
:::
:::            E - The Search must match the end of a line.
:::                Mostly used with literal searches.
:::
:::            I - Makes the search case-insensitive.
:::
:::            J - The Replace argument represents a JScript expression.
:::                The expression may access an array like arguments object
:::                named $. However, $ is not a true array object.
:::
:::                The $.length property contains the total number of arguments
:::                available. The $.length value is equal to n+3, where n is the
:::                number of capturing left parentheses within the Search string.
:::
:::                $[0] is the substring that matched the Search,
:::                $[1] through $[n] are the captured submatch strings,
:::                $[n+1] is the offset where the match occurred, and
:::                $[n+2] is the original source string.
:::
:::                Arguments $[0] through $[10] may be abbreviated as
:::                $1 through $10. Argument $[11] and above must use the square
:::                bracket notation.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in the Replace string
:::                are treated as $ literals.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line, thus enabling
:::                search for \n. This also enables preservation of the original
:::                line terminators. If the M option is not present, then every
:::                printed line is terminated with carriage return and line feed.
:::                The M option is incompatible with the A option unless the S
:::                option is also present.
:::
:::                Note: If working with binary data containing NULL bytes,
:::                      then the M option must be used.
:::
:::            S - The source is read from an environment variable instead of
:::                from stdin. The name of the source environment variable is
:::                specified in the next argument after the option string. Without
:::                the M option, ^ anchors the beginning of the string, and $ the
:::                end of the string. With the M option, ^ anchors the beginning
:::                of a line, and $ the end of a line.
:::
:::            V - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences within the Replace string:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \q     -  Quote
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Extended ASCII byte code expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Also enables the \q escape sequence for the Search string.
:::                The other escape sequences are already standard for a regular
:::                expression Search string.
:::
:::                Also modifies the behavior of \xnn in the Search string to work
:::                properly with extended ASCII byte codes.
:::
:::                Extended escape sequences are supported even when the L option
:::                is used. Both Search and Replace support all of the extended
:::                escape sequences if both the X and L opions are combined.
:::
:::  Return Codes:  0 = At least one change was made
:::                     or the /? or /V option was used
:::
:::                 1 = No change was made
:::
:::                 2 = Invalid call syntax or incompatible options
:::
:::                 3 = JScript runtime error, typically due to invalid regex
:::
::: REPL.BAT was written by Dave Benham, with assistance from DosTips user Aacini
::: to get \xnn to work properly with extended ASCII byte codes. Also assistance
::: from DosTips user penpen diagnosing issues reading NULL bytes, along with a
::: workaround. REPL.BAT was originally posted at:
::: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^:::" "" a
    exit /b 0
  ) else if /i "%~1" equ "/?regex" (
    explorer "http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/?replace" (
    explorer "http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/V" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^::(REPL\.BAT version)" "$1" a
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 2
  )
)
echo(%~3|findstr /i "[^SMILEBVXAJ]" >nul && (
  call :err "Invalid option(s)"
  exit /b 2
)
echo(%~3|findstr /i "M"|findstr /i "A"|findstr /vi "S" >nul && (
  call :err "Incompatible options"
  exit /b 2
)
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%

:err
>&2 echo ERROR: %~1. Use REPL /? to get help.
exit /b

************* JScript portion **********/
var rtn=1;
try {
  var env=WScript.CreateObject("WScript.Shell").Environment("Process");
  var args=WScript.Arguments;
  var search=args.Item(0);
  var replace=args.Item(1);
  var options="g";
  if (args.length>2) options+=args.Item(2).toLowerCase();
  var multi=(options.indexOf("m")>=0);
  var alterations=(options.indexOf("a")>=0);
  if (alterations) options=options.replace(/a/g,"");
  var srcVar=(options.indexOf("s")>=0);
  if (srcVar) options=options.replace(/s/g,"");
  var jexpr=(options.indexOf("j")>=0);
  if (jexpr) options=options.replace(/j/g,"");
  if (options.indexOf("v")>=0) {
    options=options.replace(/v/g,"");
    search=env(search);
    replace=env(replace);
  }
  if (options.indexOf("x")>=0) {
    options=options.replace(/x/g,"");
    if (!jexpr) {
      replace=replace.replace(/\\\\/g,"\\B");
      replace=replace.replace(/\\q/g,"\"");
      replace=replace.replace(/\\x80/g,"\\u20AC");
      replace=replace.replace(/\\x82/g,"\\u201A");
      replace=replace.replace(/\\x83/g,"\\u0192");
      replace=replace.replace(/\\x84/g,"\\u201E");
      replace=replace.replace(/\\x85/g,"\\u2026");
      replace=replace.replace(/\\x86/g,"\\u2020");
      replace=replace.replace(/\\x87/g,"\\u2021");
      replace=replace.replace(/\\x88/g,"\\u02C6");
      replace=replace.replace(/\\x89/g,"\\u2030");
      replace=replace.replace(/\\x8[aA]/g,"\\u0160");
      replace=replace.replace(/\\x8[bB]/g,"\\u2039");
      replace=replace.replace(/\\x8[cC]/g,"\\u0152");
      replace=replace.replace(/\\x8[eE]/g,"\\u017D");
      replace=replace.replace(/\\x91/g,"\\u2018");
      replace=replace.replace(/\\x92/g,"\\u2019");
      replace=replace.replace(/\\x93/g,"\\u201C");
      replace=replace.replace(/\\x94/g,"\\u201D");
      replace=replace.replace(/\\x95/g,"\\u2022");
      replace=replace.replace(/\\x96/g,"\\u2013");
      replace=replace.replace(/\\x97/g,"\\u2014");
      replace=replace.replace(/\\x98/g,"\\u02DC");
      replace=replace.replace(/\\x99/g,"\\u2122");
      replace=replace.replace(/\\x9[aA]/g,"\\u0161");
      replace=replace.replace(/\\x9[bB]/g,"\\u203A");
      replace=replace.replace(/\\x9[cC]/g,"\\u0153");
      replace=replace.replace(/\\x9[dD]/g,"\\u009D");
      replace=replace.replace(/\\x9[eE]/g,"\\u017E");
      replace=replace.replace(/\\x9[fF]/g,"\\u0178");
      replace=replace.replace(/\\b/g,"\b");
      replace=replace.replace(/\\f/g,"\f");
      replace=replace.replace(/\\n/g,"\n");
      replace=replace.replace(/\\r/g,"\r");
      replace=replace.replace(/\\t/g,"\t");
      replace=replace.replace(/\\v/g,"\v");
      replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      replace=replace.replace(/\\B/g,"\\");
    }
    search=search.replace(/\\\\/g,"\\B");
    search=search.replace(/\\q/g,"\"");
    search=search.replace(/\\x80/g,"\\u20AC");
    search=search.replace(/\\x82/g,"\\u201A");
    search=search.replace(/\\x83/g,"\\u0192");
    search=search.replace(/\\x84/g,"\\u201E");
    search=search.replace(/\\x85/g,"\\u2026");
    search=search.replace(/\\x86/g,"\\u2020");
    search=search.replace(/\\x87/g,"\\u2021");
    search=search.replace(/\\x88/g,"\\u02C6");
    search=search.replace(/\\x89/g,"\\u2030");
    search=search.replace(/\\x8[aA]/g,"\\u0160");
    search=search.replace(/\\x8[bB]/g,"\\u2039");
    search=search.replace(/\\x8[cC]/g,"\\u0152");
    search=search.replace(/\\x8[eE]/g,"\\u017D");
    search=search.replace(/\\x91/g,"\\u2018");
    search=search.replace(/\\x92/g,"\\u2019");
    search=search.replace(/\\x93/g,"\\u201C");
    search=search.replace(/\\x94/g,"\\u201D");
    search=search.replace(/\\x95/g,"\\u2022");
    search=search.replace(/\\x96/g,"\\u2013");
    search=search.replace(/\\x97/g,"\\u2014");
    search=search.replace(/\\x98/g,"\\u02DC");
    search=search.replace(/\\x99/g,"\\u2122");
    search=search.replace(/\\x9[aA]/g,"\\u0161");
    search=search.replace(/\\x9[bB]/g,"\\u203A");
    search=search.replace(/\\x9[cC]/g,"\\u0153");
    search=search.replace(/\\x9[dD]/g,"\\u009D");
    search=search.replace(/\\x9[eE]/g,"\\u017E");
    search=search.replace(/\\x9[fF]/g,"\\u0178");
    if (options.indexOf("l")>=0) {
      search=search.replace(/\\b/g,"\b");
      search=search.replace(/\\f/g,"\f");
      search=search.replace(/\\n/g,"\n");
      search=search.replace(/\\r/g,"\r");
      search=search.replace(/\\t/g,"\t");
      search=search.replace(/\\v/g,"\v");
      search=search.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      search=search.replace(/\\B/g,"\\");
    } else search=search.replace(/\\B/g,"\\\\");
  }
  if (options.indexOf("l")>=0) {
    options=options.replace(/l/g,"");
    search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
    if (!jexpr) replace=replace.replace(/\$/g,"$$$$");
  }
  if (options.indexOf("b")>=0) {
    options=options.replace(/b/g,"");
    search="^"+search
  }
  if (options.indexOf("e")>=0) {
    options=options.replace(/e/g,"");
    search=search+"$"
  }
  var search=new RegExp(search,options);
  var str1, str2;

  if (srcVar) {
    str1=env(args.Item(3));
    str2=str1.replace(search,jexpr?replFunc:replace);
    if (!alterations || str1!=str2) if (multi) {
      WScript.Stdout.Write(str2);
    } else {
      WScript.Stdout.WriteLine(str2);
    }
    if (str1!=str2) rtn=0;
  } else if (multi){
    var buf=1024;
    str1="";
    while (!WScript.StdIn.AtEndOfStream) {
      str1+=WScript.StdIn.Read(buf);
      buf*=2
    }
    str2=str1.replace(search,jexpr?replFunc:replace);
    WScript.Stdout.Write(str2);
    if (str1!=str2) rtn=0;
  } else {
    while (!WScript.StdIn.AtEndOfStream) {
      str1=WScript.StdIn.ReadLine();
      str2=str1.replace(search,jexpr?replFunc:replace);
      if (!alterations || str1!=str2) WScript.Stdout.WriteLine(str2);
      if (str1!=str2) rtn=0;
    }
  }
} catch(e) {
  WScript.Stderr.WriteLine("JScript runtime error: "+e.message);
  rtn=3;
}
WScript.Quit(rtn);

function replFunc($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10) {
  var $=arguments;
  return(eval(replace));
}

I have ceased development of REPL.BAT, and replaced it with JREPL.BAT. This newer utility has all the same functionality of REPL.BAT, plus much more:

  • Unicode UTF-16LE support via native CSCRIPT unicode capabilities, and any other character set (including UTF-8) via ADO.
  • Read directly from / write directly to a file: no need for pipes, redirection, or move command.
  • Incorporate user supplied JScript
  • Translation facility similar to unix tr, only it also supports regex search and JScript replace
  • Discard non-matching text
  • Prefix output lines with line number
  • and more…
:/>  Что такое win download files windows 10

As always, full documentation is embedded within the script.

The original trivial solution is now even simpler:

jrepl "foo" "bar" /f test.txt /o -

Задача замены строки или её части в текстовом файле в командной строке или в bat файле может быть решена различными способами, в зависимости от требований.

Варианты замены текста из командной строки

Утилита поиска и замены текста

Специализированный инструмент всегда даёт самый функциональный и быстрый для реализации способ: готовые утилиты поддерживают все кодировки файлов, имеют опции для разных вариантов замены, поддерживают регулярные выражения и не требуют отладки!

Единственная ситуация, когда вариант с готовой утилитой может не подойти – если есть непреодолимое требование не использовать нестандартные (не входящие в состав Windows) компоненты при развёртывании на большое число корпоративных компьютеров. Но такое встречается нечасто.

Поэтому применение готового, отлаженного и протестированного инструмента является предпочтительным вариантом!

Скрипт на JS или VBS

Возможности VBScript/JScript позволяют реализовать различные варианты замены, включая поддержку регулярных выражений, но всё-таки имеют ограниченные возможности: поддержку меньшего числа кодировок файлов, отсутствие массовой замены, отсутствие подкаталогов и т.д. Любое изменение необходимо отлаживать и тестировать. В общем, очередной «велосипед».

Вариант со скриптом оптимально использовать в случае, когда по каким-то причинам нельзя использовать готовую утилиту.

Bat файлы

О серьёзных возможностях программирования bat файлов говорить не приходится – собственно, bat файл потому и называется пакетным файлом, что предназначен для запуска списка команд по очереди, а не для программирования циклов и обработки переменных.

Сильные стороны bat файлов – удобная форма запуска команд по списку, простое перенаправление вывода и использование переменных окружения, но лучше в bat файлах не программировать.

Замена текста в файле скриптом JScript

Чтобы сделать замену текста в текстовом файле, в том числе, с использованием регулярных выражений, можно использовать следующий скрипт JScript, который:

  • открывает указанный текстовый файл
  • читает его построчно
  • для каждой строки выполняет замену по регулярному выражению

Код скрипта замены текста

// Имя файла, искомый текст и текст замены берём из аргументов
var file_name = WScript.Arguments(0);
var text_sample = WScript.Arguments(1);
var text_replace = WScript.Arguments(2);

var fso=WScript.CreateObject("Scripting.FileSystemObject");
// Переносим исходный файл во временный
var file_name_tmp = file_name+".tmp";
if (fso.FileExists(file_name_tmp))
    fso.DeleteFile(file_name_tmp);
fso.MoveFile(file_name,file_name_tmp);

var fo = fso.OpenTextFile(file_name_tmp,1,false,false);
var fr = fso.OpenTextFile(file_name,2,true,false);

// Выполняем замену текста, с построчной обработкой
var re=new RegExp(text_sample);

while (!fo.AtEndOfStream) {
    var line = fo.ReadLine();
    var line_replace = line.replace(re,text_replace);
    fr.WriteLine(line_replace);
}
fo.Close();
fr.Close();
// Удаляем временный файл
fso.DeleteFile(file_name_tmp);

Запуск скрипта замены текста

При запуске скрипта необходимо параметрами передать имя файла, строку поиска (регулярное выражение), строку замены:

cscript //nologo replace_text.js content.txt Foo Bar

Примечания к скрипту

Скрипт обрабатывает файлы в ANSI кодировке. Для Unicode файла необходимо заменить 4-й аргумент в вызовах OpenTextFile c false на true.

:/>  Что такое Install Wim что это за устройство? Как создать instagram для Windows 10

Поскольку обработка ведётся по строкам, то регулярные выражения сработают только в пределах одной строки.

Примеры использования скрипта replace-text-script-samples.zip

Замена текста программой nhrt

Больше возможностей и гибкости: поддержка всех кодировок файлов с автоматическим определением, пакетная обработка и многое другое в программе nhrt.

Renaming 1 file in cmd is very easy:
In this example we have a sample1.txt and we want to change its name to sample2.txt:

    in command prompt type:
    c:\temp> ren sample1.txt sample2.txt [enter]

Let’s say the filename is sample1-some-unwanted-text-1234.txt and we want to change it to sample1.txt:

    in command prompt, type:
    c:\temp> ren sample1-some-unwanted-text-1234.txt sample1.txt

Renaming 1 file by replacing multiple unwanted characters using a star:
Let’s say the filename is sample1-some-unwanted-text-1234.txt and we want to change it to sample1.txt without having to type the whole filename:

    in command prompt:
    c:\temp> ren sample1*.txt sample1.txt

This * basically means any characters inbetween sample1 and .txt will be replaced.

Renaming multiple files with similar names
If you want to rename multiple files, i.e. sample1 2020-08-01.txt, sample2 2020-08-05.txt, sample3 2020-08-10.txt,sample4 2020-08-13.txt, you want to keep the first 7 characters you want to get rid of the dates:

    in command prompt:
    c:\temp> ren sample?*.txt sample?.txt

In this example, you want to keep the word sample and the number X (where X can be any number or character). Using a ? will leave the number in place and * instructs the rename-command to replace any characters in between sampleX and .txt

Warning: It happens very quickly that a command prompt rename operation renames too many files and you can’t undo it. So, when renaming multiple files it is advisable to make a copy of all the files you want to rename, put them in a temp folder, then run your rename commands in the temp folder, and when you’re certain that it works, go back and rename the original files.

В продолжении темы Cmd – хаков, опишу еще несколько эффективных приемов работы с командной строкой.

>> Что такое enabledelayedexpansion?

Вообще я не хотел писать об этом, но т.к. в следующем примере это используется и в справке расписано туманно, напишу.

Обычно при использовании переменных в bat/cmd сценариях используется конструкция %переменная%, однако если значение переменной меняется в теле цикла и считывается там же, это может не работать. Например:

Теперь все выводится как и задумано. Замечу что переменная в данном случае обрамлена восклицательными знаками (!).

>> Создание динамических переменных в bat-файлах? Легко!

При написании сценариев командной строки, у администраторов, которые, хотя бы немного программировали на других языках программирования (а cmd можно отнести к ним с натяжкой) возникает определенный дискомфорт при обработке  больших массивов данных. Ведь в cmd отсутствуют массивы! Мы можем обойти это ограничение с использованием динамических переменных. Для этого воспользуемся расширенным режимом обработки команд.

Например есть текстовый файл, нам нужно его прочитать и вывести определенные строки на экран, покажу как это сделать при помощи динамических переменных.

Для начала создадим файл greeka.txt  с таким содержимым:

1.Ехал Грека через реку,Видит Грека – в реке рак.

2.Ехал Грека через реку,Видит Грека – в реке рак.

3.Ехал Грека через реку,Видит Грека – в реке рак.

4.Ехал Грека через реку,Видит Грека – в реке рак.

5.Ехал Грека через реку,Видит Грека – в реке рак.

6.Ехал Грека через реку,Видит Грека – в реке рак.

7.Ехал Грека через реку,Видит Грека – в реке рак.

8.Ехал Грека через реку,Видит Грека – в реке рак.

9.Ехал Грека через реку,Видит Грека – в реке рак.

10.Ехал Грека через реку,Видит Грека – в реке рак.

Далее, приступим к написанию нашего сценария:

Включаем режим расширенной обработки команд.

Объявляем вспомогательную переменную.

    for /F “tokens=*” %%a in (greka.txt) do (

Начало цикла  построчного перебора файла.

      set /A i=!i! + 1

Увеличиваем вспомогательный итератор на единицу. 

Собственно сама незамысловатая конструкция создания динамических переменных, с именами str1, str2, str3 и так далее.

Проверим как отработал наш сценарий.

Как видим динамические переменные использовать довольно удобно и легко, они могут помочь вам заменить массивы и добавят гибкости коду.

>> Поиск и замена текста в файлах средствами cmd/bat файла.

Многие администраторы и Power-пользователи линукс, при знакомстве с возможностями cmd, замечают такую досадную деталь, как отсутствие множества утилит для поиска и замены подстрок в  файлах.

Вообще под windows существует множество утилит для обработки строк в файлах, в том числе и портированных с #nix систем (тот же sed и supersed), но мы не ищем легких путей это будет не совсем чисто, т.к. в нужный момент этого всего может не оказаться под рукой.

Возможна ли реализация данной функции на cmd ? Конечно! А поможет нам в этом специальные строки расширения, а точнее конструкция  вида %переменная:A=B%, где переменная– переменная содержащая исходную подстроку, A – подстрока которую ищем, B – подстрока на которую меняем искомую подстроку в строке.

Приступим писать наш код, т.к. он очень похож на тот что выше, особо вдаваться в детали я не буду:

rem Собираем параметры командой строки переданной сценарию.
rem Например сценарий запущен “File_str_replace.bat greka.txt Грека Гитлер”
rem %1 = greka.txt %2=Грека %3=Гитлер
Set infile=%1
Set find=%2
Set replace=%3

    for /F “tokens=* delims=,” %%n in (!infile!) do (
    set LINE=%%n

REM Именно здесь происходит замена текущей строки!

REM Добавляем строку к временному файлу
                    )

copy %infile% %infile%.bak

REM Заменяем исходный файл временным

move TMP.TXT %infile%

Наш батник для поиска и замены подстрок файла готов. Теперь сгенерируем файл для него, да побольше! Сделаем это тоже батником:

На сегодня пожалуй все, попозже продолжу.

Replace

Заменяет файлы в одном каталоге файлами с теми же именами из другого каталога. Команда
replace также может быть использована для добавления только тех файлов, которых еще
нет в каталоге.

Параметры

[диск1:][путь1] имя_файла
Задает местонахождение и имя файла или набора исходных файлов.
[диск2:][путь2]
Задает местонахождение файла-результата. Имена замещаемых файлов не могут быть заданы. Если
ни диск, ни каталог не заданы, replace использует текущий диск и текущий каталог.
/a
Добавляет, а не перезаписывает файлы в каталог-результат. Нельзя использовать данный
параметр совместно с параметром /s или /u.
/p
Добавляет или перезаписывает файлы с подтверждением.
/r
Замещает файлы, предназначенные только для чтения, так же, как и обычные файлы. Если этот
параметр не задан, а программа пытается заменить файл, предназначенный только для чтения,
на экран будет выведено сообщение об ошибке и операция замены будет остановлена.
/w
Перед началом поиска исходных файлов система будет ждать, пока пользователь вставит диск в
дисковод. Если ключ /w не задан, замена или добавление фалов начнется сразу же после
нажатия клавиши ENTER.
/s
Ищет по всем подкаталогам каталога-назначения и заменяет файлы с подходящими именами.
Нельзя использовать параметр /s совместно с параметром командной строки /a.
Команда replace не ищет подкаталоги, указанные параметром путь1.
/u
Заменяет (обновляет) только те файлы, которые имеют более раннюю дату модификации, чем
файлы в исходном каталоге. Нельзя использовать параметр /u совместно с параметром
командной строки /a.
/?
Отображает справку в командной строке.
:/>  Инструкция по настройке фонового изображения для ноутбука с Windows 7 и модификации заставки на рабочем столе Windows 7 при отсутствии настроек персонализации?

Примеры

Предположим, что несколько каталогов на диске C содержат различные версии файла Phones.cli,
который включает имена клиентов и их телефонные номера. Для замены всех этих файлов новейшей
версией с диска в дисководе A служит следующая команда:

replace a:\phones.cli c:\ /s

Предположим, требуется добавить новый драйвер принтера в каталог Tools на диске C, в котором
уже содержится несколько файлов драйверов принтеров для текстовых процессоров.

replace a:*.prd c:\tools /a

Эта команда просматривает текущий каталог диска A и находит все файлы с расширением .prd, а
затем добавляет эти файлы в каталог Tools на диске C. Так как задан параметр /a,
команда replace добавит только те файлы, которых еще нет на диске C.

Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать
раздел форума
этого сайта (требуется регистрация).

Как известно, перевод строки в текстовых файлах может быть представлен различными символами, из которых сами популярные варианты это:

  • LF (Unix)
  • CR+LF (Windows)

Более подробное описание и историю можно почитать, например, в Википедии. С практической же точки зрения эти различия приводят к тому, что файлы могут интерпретироваться неправильно при переносе между платформами. Например, так выглядит текстовый файл с юниксовыми переводами строк в Блокноте Windows:

Текстовый файл с переводами строки Unix (LF) в Блокноте Windows

Проблема актуальна для всех видов текстовых файлов – как обычных TXT, так и программного кода C, HTML, PHP и т.д.

Разовую замену переводов строк в небольшом числе файле можно сделать, например, в программе Notepad++.

При большом количестве текстовых файлов и при необходимости обработки в командной строке удобно использовать бесплатную программу nhrt, которая может заменить переводы строк в командной строке и bat файле, при этом предназначена для использования в командной строке и пакетных файлах, а также поддерживает маски файлов и подкаталоги.

Замена переводов строки Unix на Windows

Для этого преобразования необходимо задать замену символа LF на последовательность CR LF командой:

nhrt -set:"\n" -et:"\r\n" NEWS.txt

После выполнения команды обновлённый файл NEWS.txt нормально открывается в Блокноте Windows:

Текстовый файл с преобразованными переводами строк Windows в Блокноте Windows
Команда для замены LF на CR LF для всех PHP файлов, включая подкаталоги:

nhrt -set:"\n" -et:"\r\n" -r *.php

Замена переводов строки Windows на Unix

Для этого преобразования необходимо задать замену последовательности CR LF на символ LF командой:

nhrt -set:"\n" -et:"\r\n" NEWS.txt

Команда для замены CR LF на LF для всех PHP файлов, включая подкаталоги:

nhrt -set:"\n" -et:"\r\n" -r *.php

Узнать больше

Параметр -set, -searchescapetext задает поиск простого текста (plain text) с поддержкой escape последовательностей.

Параметр -et, -escapetext задает заменяющий текст с поддержкой escape последовательностей.

Команда REPLACE используется для замены одного или нескольких файлов в командной строке Windows. Применяется в для синхронизации содержимого каталогов и перезаписи только тех файлов, которые изменились позже, чем дата изменения существующих.

1. Описание команды REPLACE.

1.1. Формат командной строки:

1.1.1. Добавление файлов:

C:\ REPLACE [диск1:][путь1]имя_файла [диск2:][путь2] [/A] [/P] [/R] [/W]

1.1.2. Замена файлов на новые:

C:\ REPLACE [диск1:][путь1]имя_файла [диск2:][путь2] [/P] [/R] [/S] [/W] [/U]

1.2. Параметры командной строки:

  • [диск1:][путь1]имя_файла — Один или несколько исходных файлов.
  • [диск2:][путь2] — Каталог, в котором следует заменить файлы.
  • /A — Добавление новых файлов в конечный каталог. Этот ключ несовместим с ключами /S и /U.
  • /P — Вывод запроса перед заменой или добавлением файла.
  • /R — Разрешение замены файлов, предназначенных только для чтения (среди прочих).
  • /S — Замена файлов во всех подкаталогах конечного каталога. Этот ключ несовместим с ключом /A.
  • /W — Ожидание вставки диска перед началом выполнения.
  • /U — Замена только файлов, более старых, чем исходные. Этот ключ несовместим с ключом /A.

Команда REPLACE не позволяет обновить файлы, имеющие атрибуты ”Скрытый” и ”Системный”.

2. Примеры использования.

2.1. Отобразить подсказку по использованию.

C:\ replace /?

2.2. Добавить файл doc2.doc из каталога Folder1 диска C: в каталог Folder2 диска D:

C:\ replace c:\Folder1\doc2.doc D:\folder2 /A

2.3. Добавить все недостающие файлы из каталога Folder1 диска C: в каталог Folder2 диска D:

C:\ replace c:\Folder1\*.* D:\folder2 /A

2.4. Заменить все файлы с расширением .docx в каталоге Folder2 диска D: на файлы из каталога Folder1 диска C:

C:\ replace c:\Folder1\*.docx D:\folder2 /U

Выполняется замена только тех файлов, у которых время изменения меньше, чем время заменяющего файла. Данная команда используется для синхронизации содержимого двух каталогов, содержащих одинаковый набор файлов с отличающимся содержимым.

Если исходный и конечный файл имеют одно и то же время модификации, то замена не выполняется. Код завершения ERRORLEVEL устанавливается в 0 независимо от того, выполнялась перезапись конечного файла или нет. При перезаписи, программа выводит на экран сообщение о замене существующего файла:

Замена D:\folder2\doc1.doc

В случае, когда перезапись не выполняется – сообщение о замене файла отсутствует. Возможные значения ERRORLEVEL при неудачном выполнении команды:

  • ERRORLEVEL=3 – не найдены пути исходных или конечных файлов.
  • ERRORLEVEL=11 – недопустимая комбинация параметров командной строки.

CMD/BAT – Замена строки в файле строкой из другого файла – нужна помощь

Оставьте комментарий