Как найти и заменить текст в файле, используя среду командной строки Windows?
Я пишу сценарий пакетного файла, используя среду командной строки Windows, и хочу заменить каждое вхождение некоторого текста в файле (например, "FOO") другим (например, "BAR"). Какой самый простой способ сделать это? Есть встроенные функции?
31 ответ
Если у вас версия Windows, которая поддерживает.Net 2.0, я бы заменил вашу оболочку. PowerShell дает вам всю мощь.Net из командной строки. Есть много встроенных командлетов. Пример ниже решит ваш вопрос. Я использую полные названия команд, есть более короткие псевдонимы, но это дает вам кое-что для Google.
(Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
Многие ответы здесь помогли мне указать верное направление, однако ни один из них не подошел для меня, поэтому я публикую свое решение.
У меня Windows 7, которая поставляется со встроенным PowerShell. Вот скрипт, который я использовал, чтобы найти / заменить все экземпляры текста в файле:
powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File myFile.txt"
Чтобы объяснить это:
powershell
запускает powershell.exe, который входит в состав Windows 7-Command "... "
командная строка для powershell.exe, содержащая команду для запуска(gc myFile.txt)
читает содержаниеmyFile.txt
(gc
коротка дляGet-Content
команда)-replace 'foo', 'bar'
просто запускает команду замены для заменыfoo
сbar
| Out-File myFile.txt
направляет вывод в файлmyFile.txt
Powershell.exe уже должен быть частью вашего оператора PATH, но если нет, вы можете добавить его. Расположение его на моей машине C:\WINDOWS\system32\WindowsPowerShell\v1.0
Только что использовал FART (утилита командной строки "F ind A nd R eplace T ext"):
отличная небольшая бесплатная программа для замены текста в большом наборе файлов.
Установочные файлы находятся на SourceForge.
Пример использования:
fart.exe -p -r -c -- C:\tools\perl-5.8.9\* @@APP_DIR@@ C:\tools
будет предварительно выполнять рекурсивные замены в файлах этого дистрибутива Perl.
Единственная проблема: иконка сайта FART не совсем со вкусом, изысканно или элегантно;)
Обновление 2017 года (7 лет спустя) jagb отмечает в комментариях к статье 2011 года " FARTing the Easy Way - найдите и замените текст" от Mikail Tunç
Заменить - заменить подстроку с помощью подстановки строк. Описание: для замены подстроки другой строкой используйте функцию подстановки строк. Показанный здесь пример заменяет все вхождения "те" орфографические ошибки на "the" в строковой переменной str.
set str=teh cat in teh hat
echo.%str%
set str=%str:teh=the%
echo.%str%
Выход скрипта:
teh cat in teh hat
the cat in the hat
Создайте файл replace.vbs:
Const ForReading = 1
Const ForWriting = 2
strFileName = Wscript.Arguments(0)
strOldText = Wscript.Arguments(1)
strNewText = Wscript.Arguments(2)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, strOldText, strNewText)
Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
objFile.Write strNewText 'WriteLine adds extra CR/LF
objFile.Close
Чтобы использовать этот пересмотренный скрипт (который мы будем называть replace.vbs), просто наберите в командной строке команду, похожую на эту:
cscript replace.vbs "C:\Scripts\Text.txt" "Jim " "James "
BatchSubstitute.bat
на dostips.com - пример поиска и замены с использованием чистого командного файла.
Он использует комбинацию FOR
, FIND
а также CALL SET
,
Строки, содержащие символы среди "&<>]|^
может рассматриваться неправильно.
Примечание. Обязательно посмотрите обновление в конце этого ответа, чтобы найти ссылку на превосходный JREPL.BAT, заменяющий REPL.BAT.
JREPL.BAT 7.0 и выше изначально поддерживает Unicode (UTF-16LE) через /UTF
вариант, а также любой другой набор символов, в том числе UTF-8, через ADO!!!!
Я написал небольшую гибридную утилиту JScript/batch REPL.BAT, которая очень удобна для изменения файлов ASCII (или расширенного ASCII) через командную строку или пакетный файл. Чисто нативный сценарий не требует установки какого-либо стороннего исполняемого файла, и он работает на любой современной версии Windows начиная с XP. Это также очень быстро, особенно по сравнению с чистыми пакетными растворами.
REPL.BAT просто читает стандартный ввод, выполняет поиск и замену регулярных выражений JScript и записывает результат в стандартный вывод.
Вот тривиальный пример того, как заменить foo на bar в test.txt, если предположить, что REPL.BAT находится в вашей текущей папке или, что еще лучше, где-то в вашей переменной PATH:
type test.txt|repl "foo" "bar" >test.txt.new
move /y test.txt.new test.txt
Возможности регулярного выражения JScript делают его очень мощным, особенно способность заменяющего текста ссылаться на захваченные подстроки из текста поиска.
Я включил в утилиту ряд опций, которые делают ее довольно мощной. Например, объединяя M
а также X
опции позволяют модифицировать двоичные файлы! M
Многострочная опция позволяет выполнять поиск по нескольким строкам. X
Опция расширенного шаблона подстановки предоставляет escape-последовательности, которые позволяют включать любое двоичное значение в текст замены.
Вся утилита могла быть написана как чистый JScript, но гибридный пакетный файл избавляет от необходимости явно указывать CSCRIPT каждый раз, когда вы хотите использовать утилиту.
Вот скрипт REPL.BAT. Полная документация встроена в скрипт.
@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));
}
ВАЖНОЕ ОБНОВЛЕНИЕ
Я прекратил разработку REPL.BAT и заменил ее на JREPL.BAT. Эта новая утилита имеет все те же функциональные возможности REPL.BAT, а также многое другое:
- Поддержка Unicode UTF-16LE через собственные возможности Unicode CSCRIPT и любой другой набор символов (включая UTF-8) через ADO.
- Чтение непосредственно из / запись непосредственно в файл: нет необходимости в каналах, перенаправлении или команде перемещения.
- Включить пользовательский JScript
- Средство перевода похоже на unix tr, только оно также поддерживает поиск по регулярным выражениям и замену JScript
- Отменить несоответствующий текст
- Префикс выходных строк с номером строки
- и больше...
Как всегда, полная документация встроена в скрипт.
Оригинальное тривиальное решение теперь стало еще проще:
jrepl "foo" "bar" /f test.txt /o -
Текущая версия JREPL.BAT доступна на DosTips. Прочитайте все последующие сообщения в ветке, чтобы увидеть примеры использования и историю развития.
Использовать FNR
Использовать fnr
полезность. У него есть некоторые преимущества перед fart
:
- Регулярные выражения
- Дополнительный графический интерфейс. Имеет "Создать кнопку командной строки" для создания текста командной строки для помещения в командный файл.
- Многострочные шаблоны: графический интерфейс позволяет легко работать с многострочными шаблонами. В FART вы должны вручную избегать разрывов строк.
- Позволяет выбрать кодировку текстового файла. Также есть опция автоматического определения.
Загрузите FNR здесь: http://findandreplace.codeplex.com/
Пример использования:fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"
Я знаю, что я опоздал на вечеринку..
Лично мне нравится решение по адресу: - http://www.dostips.com/DtTipsStringManipulation.php
Мы также широко используем функцию дедупликации, чтобы помочь нам ежедневно доставлять около 500 электронных писем по SMTP из: - https://groups.google.com/forum/
и оба они работают изначально без дополнительных инструментов или утилит, необходимых.
Заменитель
DEL New.txt
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (OLD.txt) do (
Set str=%%a
set str=!str:FOO=BAR!
echo !str!>>New.txt
)
ENDLOCAL
DEDUPLICATOR (обратите внимание на использование -9 для номера ABA):
REM DE-DUPLICATE THE Mapping.txt FILE
REM THE DE-DUPLICATED FILE IS STORED AS new.txt
set MapFile=Mapping.txt
set ReplaceFile=New.txt
del %ReplaceFile%
::DelDupeText.bat
rem https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o
setLocal EnableDelayedExpansion
for /f "tokens=1,2 delims=," %%a in (%MapFile%) do (
set str=%%a
rem Ref: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.RightString
set str=!str:~-9!
set str2=%%a
set str3=%%a,%%b
find /i ^"!str!^" %MapFile%
find /i ^"!str!^" %ReplaceFile%
if errorlevel 1 echo !str3!>>%ReplaceFile%
)
ENDLOCAL
Спасибо!
Когда вы работаете с Git в Windows, просто запустите git-bash
и использовать sed
, Или, при использовании Windows 10, запустите "Bash на Ubuntu в Windows" (из подсистемы Linux) и используйте sed
,
Это потоковый редактор, но он может редактировать файлы напрямую, используя следующую команду:
sed -i -e 's/foo/bar/g' filename
-i
опция используется для редактирования на месте имени файла.-e
опция указывает команду для запуска.s
используется для замены найденного выражения "foo" на "bar" иg
используется для замены любых найденных совпадений.
Примечание от ereOn:
Если вы хотите заменить строку в версионных файлах только Git-репозитория, вы можете использовать:
git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'
который творит чудеса.
Я использовал Perl, и это прекрасно работает.
perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" <fileName>
.orig - это расширение, которое будет добавлено к исходному файлу.
Для ряда подходящих файлов, таких как *.html
for %x in (<filePattern>) do perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" %x
Я поиграл с некоторыми из существующих ответов здесь и предпочел бы мое улучшенное решение...
type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }"
или если вы хотите снова сохранить вывод в файл...
type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }" > outputFile.txt
Преимущество этого заключается в том, что вы можете передавать данные из любой программы. Также рассмотрим использование регулярных выражений. Не могу понять, как превратить его в BAT-файл для более легкого использования...:-(
1) с e?
опция, которая будет оценивать специальные последовательности символов, такие как \n\r
и последовательности Юникода. В этом случае заменим указанные "Foo"
а также "Bar"
:
call replacer.bat "e?C:\content.txt" "\u0022Foo\u0022" "\u0022Bar\u0022"
2) Простая замена, где Foo
а также Bar
не котируются
call replacer.bat "C:\content.txt" "Foo" "Bar"
Вот решение, которое я нашел, работало на Win XP. В мой рабочий пакетный файл я включил следующее:
set value=new_value
:: Setup initial configuration
:: I use && as the delimiter in the file because it should not exist, thereby giving me the whole line
::
echo --> Setting configuration and properties.
for /f "tokens=* delims=&&" %%a in (config\config.txt) do (
call replace.bat "%%a" _KEY_ %value% config\temp.txt
)
del config\config.txt
rename config\temp.txt config.txt
replace.bat
Файл как ниже. Я не нашел способ включить эту функцию в тот же пакетный файл, потому что %%a
Кажется, переменная всегда дает последнее значение в цикле for.
replace.bat
:
@echo off
:: This ensures the parameters are resolved prior to the internal variable
::
SetLocal EnableDelayedExpansion
:: Replaces Key Variables
::
:: Parameters:
:: %1 = Line to search for replacement
:: %2 = Key to replace
:: %3 = Value to replace key with
:: %4 = File in which to write the replacement
::
:: Read in line without the surrounding double quotes (use ~)
::
set line=%~1
:: Write line to specified file, replacing key (%2) with value (%3)
::
echo !line:%2=%3! >> %4
:: Restore delayed expansion
::
EndLocal
Посмотрите, есть ли какая-нибудь утилита типа sed для cmd.exe, которая запрашивает эквивалент sed под Windows, должна также применяться к этому вопросу. Управляющее резюме:
- Это может быть сделано в пакетном файле, но это не красиво
- Множество доступных сторонних исполняемых файлов, которые сделают это за вас, если у вас есть возможность установить или просто скопировать exe
- Может быть сделано с VBScript или аналогичным, если вам нужно что-то, что может работать на Windows-коробке без изменений и т. Д.
Два пакетных файла, которые поставляют search and replace
функции были написаны членами переполнения стека dbenham
а также aacini
с помощью native built-in jscript
в винде.
Они оба robust
а также very swift with large files
по сравнению с обычными пакетными сценариями, а также simpler
использовать для базовой замены текста. У них обоих Windows regular expression
сопоставление с образцом.
это
sed-like
Вспомогательный пакетный файл называетсяrepl.bat
(от dbenham).Пример использования
L
буквальный переключатель:echo This is FOO here|repl "FOO" "BAR" L echo and with a file: type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
это
grep-like
Вспомогательный пакетный файл называетсяfindrepl.bat
(аачини).Пример с активными регулярными выражениями:
echo This is FOO here|findrepl "FOO" "BAR" echo and with a file: type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"
Оба становятся мощными общесистемными утилитами when placed in a folder that is on the path
, или может использоваться в той же папке с командным файлом, или из командной строки cmd.
У них обоих case-insensitive
переключатели, а также многие другие функции.
Я предпочитаю использовать sed
из утилит GNU для Win32, следует отметить следующее
- одиночная цитата
''
не будет работать в Windows, используйте""
вместоsed -i
не будет работать в Windows, ему потребуется обмен файлами
Так что рабочий код sed
найти и заменить текст в файле в Windows, как показано ниже
sed -e "s/foo/bar/g" test.txt > tmp.txt && mv tmp.txt test.txt
Может быть, немного поздно, но я часто ищу подобные вещи, так как я не хочу переживать боль одобрения программного обеспечения.
Однако вы обычно используете оператор FOR в различных формах. Кто-то создал полезный командный файл, который выполняет поиск и замену. Посмотрите здесь. Важно понимать ограничения предоставляемого командного файла. По этой причине я не копирую исходный код в этом ответе.
Команда Power Shell работает как шарм
(
test.txt | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
)
Используйте powershell в.bat - для Windows 7+
кодировка utf8 не является обязательной, хорошо для веб-сайтов
@echo off
set ffile='myfile.txt'
set fold='FOO'
set fnew='BAR'
powershell -Command "(gc %ffile%) -replace %fold%, %fnew% | Out-File %ffile% -encoding utf8"
Для меня, чтобы не менять кодировку (с UTF-8), сохраняя акценты ... единственный способ - указать кодировку по умолчанию до и после:
powershell -Command "(gc 'My file.sql' -encoding "Default") -replace 'String 1', 'String 2' | Out-File -encoding "Default" 'My file.sql'"
Просто столкнулся с похожей проблемой - "Поиск и замена текста в файлах", но за исключением того, что для имен файлов и поиска / повторного использования мне нужно использовать регулярное выражение. Поскольку я не знаком с Powershell и хочу сохранить результаты поиска для последующего использования, мне нужно что-то более "удобное для пользователя" (предпочтительно, если оно имеет графический интерфейс).
Итак, пока гуглил:) я нашел отличный инструмент - FAR (Find And Replace) (не FART).
Эта небольшая программа имеет приятный графический интерфейс и поддержку регулярных выражений для поиска в именах файлов и в файлах. Единственным недостатком является то, что если вы хотите сохранить свои настройки, вы должны запустить программу от имени администратора (по крайней мере, на Win7).
Это одна вещь, которую пакетные сценарии просто не делают хорошо.
Сценарий, на который ссылается morechilli, будет работать для некоторых файлов, но, к сожалению, он будет подавлен теми, которые содержат символы, такие как трубы и амперсанды.
VBScript - лучший встроенный инструмент для этой задачи. См. Эту статью для примера: http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx
@Rachel дала отличный ответ, но здесь есть вариант, чтобы читать контент в PowerShell $data
переменная. Затем вы можете легко манипулировать контентом несколько раз перед записью в выходной файл. Также посмотрите, как многострочные значения приведены в пакетных файлах.bat.
@REM ASCII=7bit ascii(no bom), UTF8=with bom marker
set cmd=^
$old = '\$Param1\$'; ^
$new = 'Value1'; ^
[string[]]$data = Get-Content 'datafile.txt'; ^
$data = $data -replace $old, $new; ^
out-file -InputObject $data -encoding UTF8 -filepath 'datafile.txt';
powershell -NoLogo -Noninteractive -InputFormat none -Command "%cmd%"
Я автор Aba Search and Replace, которую вы можете использовать из командной строки Windows . Он может выполнять пакетную замену без какого-либо взаимодействия с пользователем, а также заменять текст в нескольких файлах, а не только в одном файле.
Приглашаем вас попробовать мой инструмент; Буду рад ответить на любые вопросы.
Загрузите Cygwin (бесплатно) и используйте unix-подобные команды в командной строке Windows.
Ваша лучшая ставка: сед
Команда Powershell -
Получение содержимого файла и замена его другим текстом с последующим сохранением в другом файле
Команда -1 (Get-Content filename.xml)| ForEach-Object {$_. Replace("some_text","replace_text"). Replace("some_other_text","replace_text")} | Set-Content filename2.xml
Копирование другого файла в исходный файл
Command2
Копировать-Item -Path filename2.xml -Destination filename.xml -PassThru
удаление еще одного файла
Команда 3
Удалить элемент filename2.xml
Также можно увидеть инструменты Replace и ReplaceFilter по адресу https://zoomicon.github.io/tranXform/ (источник включен). Второй - это фильтр.
Инструмент, который заменяет строки в файлах, находится в VBScript (для работы в старых версиях Windows требуется Windows Script Host [WSH])
Фильтр, вероятно, не работает с Unicode, если вы не перекомпилируете с последней версией Delphi (или с FreePascal/Lazarus)