bat文件替换文本文件中的字符串 [英] bat file to replace string in text file

查看:1379
本文介绍了bat文件替换文本文件中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题已经被问在计算器很多,但我似乎无法能够使它发挥作用。任何提示AP preciated。这里是需要被除去的文本文件(扩展名为.mpl)含有违规文本:

This question has been asked a lot on stackoverflow, but I can't seem to be able to make it work. Any hints appreciated. Here is a text file (extension .mpl) containing offending text that needs to be removed:

plotsetup('ps', 'plotoutput = "plotfile.eps"', 'plotoptions' = "color=rgb,landscape,noborder");
print(PLOT3D(MESH(Array(1..60, 1..60, 1..3, [[[.85840734641021,0.,-0.],
[HFloat(undefined),HFloat(undefined),HFloat(undefined)],[.857971665313419,.0917163905694189,-.16720239349226],
... more like that ...
[.858407346410207,-3.25992468340355e-015,5.96532373555817e-015]]], datatype = float[8], order = C_order)),SHADING(ZHUE),STYLE(PATCHNOGRID),TRANSPARENCY(.3),LIGHTMODEL(LIGHT_4),ORIENTATION(35.,135.),SCALING(CONSTRAINED),AXESSTYLE(NORMAL)));

我要删除的每个实例:

I want to remove every instance of:

[HFloat(undefined),HFloat(undefined),HFloat(undefined)],

和有成千上万这样的情况!注意:方括号和逗号将被删除。没有空间,所以我的页面和页面:

and there are thousands such instances!. Note: the square brackets and the comma are to be removed. There is no space, so I have pages and pages of:

[HFloat(undefined),HFloat(undefined),HFloat(undefined)],   
[HFloat(undefined),HFloat(undefined),HFloat(undefined)],   
[HFloat(undefined),HFloat(undefined),HFloat(undefined)],

我不会在这里列出我所有的失败的尝试。下面是我来最接近的:

I won't list here all my failed attempts. Below is the closest I've come:

@echo off

SetLocal 
cd /d %~dp0

if exist testCleaned.mpl del testCleaned.mpl

SetLocal EnableDelayedExpansion

Set OldString=[HFloat(undefined),HFloat(undefined),HFloat(undefined)],
Set NewString=

pause

FOR /F "tokens=* delims= " %%I IN (test.mpl) DO (
    set str=%%I
    set str=!str:OldString=NewString!
    echo !str! >> testCleaned.mpl
    endlocal
)

EndLocal

以上是串在一起的,因为它是从code片在网络上找到,尤其是在计算器,例如问题的搜索和替换批处理文件

它的作用是产生一个截断的文件,内容如下:

What it does is produce a truncated file, as follows:

plotsetup('ps', 'plotoutput = "plotfile.eps"', 'plotoptions' = "color=rgb,landscape,noborder"); 
!str! 

请不要犹豫,要求澄清。道歉,如果你觉得这个问题已经有了答案。我非常AP preciate如果你想复制粘贴相关code对我来说,因为我已经尝试了好几个小时。

Please don't hesitate to request clarifications. Apologies if you feel that this question has already been answered. I would very much appreciate if you would copy-paste the relevant code for me, as I have tried for several hours.

奖励:这可以自动命名进行工作? %%〜nICleaned.mpl

Bonus: can this automatic naming be made to work? "%%~nICleaned.mpl"

推荐答案

与您现有的code而言,最大的问题是 SETLOCAL enableDelayedExpansion 是missplaced - 它应该是集海峡后内环路= %%我

The biggest problem with your existing code is the SetLocal enableDelayedExpansion is missplaced - it should be within the loop after set str=%%I.

其他问题:


  • 将去掉开头的行;

  • 将移除每一行前导空格

  • 将去除空白(空)行

  • 将打印 ECHO处于关闭状态如有线为空或替换后只包含空格

  • 将在每行的末尾添加额外的空间(没有注意到这一点,直到我读了杰布的答案)

  • will strip lines beginning with ;
  • will strip leading spaces from each line
  • will strip blank (empty) lines
  • will print ECHO is off if any lines becomes empty or contains only spaces after substitution
  • will add extra space at end of each line (didn't notice this until I read jeb's answer)

优化问题 - 使用>> 可以相对缓慢。这是更快地括在整个循环(),然后使用>

Optimization issue - using >> can be relatively slow. It is faster to enclose the whole loop in () and then use >

下面是你可以使用Windows批量做到最好。我自动命名为要求的输出,做的更好 - 它可以自动preserves原来的扩展名

Below is about the best you can do with Windows batch. I auto named the output as requested, doing one better - It automatically preserves the extension of the original name.

@echo off
SetLocal
cd /d %~dp0
Set "OldString=[HFloat(undefined),HFloat(undefined),HFloat(undefined)],"
Set "NewString="
set file="test.mpl"
for %%F in (%file%) do set outFile="%%~nFCleaned%%~xF"
pause
(
  for /f "skip=2 delims=" %%a in ('find /n /v "" %file%') do (
    set "ln=%%a"
    setlocal enableDelayedExpansion
    set "ln=!ln:*]=!"
    if defined ln set "ln=!ln:%OldString%=%NewString%!"
    echo(!ln!
    endlocal
  )
)>%outFile%

已知的限制


  • 限于略低于每行8K之前和替换之后

  • 搜索字符串不能包括 = ,也无法使用启动*

  • 替换字符串不能包括

  • 搜索
  • 搜索部和替换不区分大小写

  • 最后一行将始终以换行符结束< CR>< LF> 即使原来没有

  • limited to slightly under 8k per line, both before and after substitution
  • search string cannot include = or !, nor can it start with * or ~
  • replacement string cannot include !
  • search part of search and replace is case insensitive
  • last line will always end with newline <CR><LF> even if original did not

除了第一个限制可能会被淘汰,但它需要大量的code,并且将速度惊人缓慢。该解决方案将需要由字符搜索每一行的一个字符。最后限制将需要一些尴尬测试以确定是否最后一行被换行终止,然后最后一行将不得不使用被打印&下;!LN = LNNUL SET / P 欺骗,如果没有新行想要的。

All but the first limitation could be eliminated, but it would require a lot of code, and would be horrifically slow. The solution would require a character by character search of each line. The last limitation would require some awkward test to determine if the last line was newline terminated, and then last line would have to be printed using <nul SET /P "ln=!ln!" trick if no newline wanted.

有趣的功能(或限制,取决于视角)

Interesting feature (or limitation, depending on perspective)


  • Unix类型文件结束与行&LT; LF&GT; 将转换到Windows风格的结尾行&LT; CR&GT;&LT; LF&GT;

  • Unix style files ending lines with <LF> will be converted to Windows style with lines ending with <CR><LF>

有使用批处理是显著更快的其他解决方案,但他们都有更多的限制。

There are other solutions using batch that are significantly faster, but they all have more limitations.

更新 - 我已经发布了一个新的纯一批解决方案,能够做到区分大小写的搜索,并且搜索或替换字符串的内容没有任何限制。它确实有上线的长度更多的限制,尾随控制字符和线条的格式。性能也不错,特别是如果更换的数量是低的。的的 http://www.dostips.com/forum/viewtopic.php?f=3&t=2710

附录

根据下面的评论中,一批解决方案不会为这一特定问题的工作,因为线路长度的限制。

Based on comments below, a batch solution will not work for this particular problem because of line length limitation.

但是,这code是一批基于搜索的良好基础和替换工具,只要你愿意忍受的限制和一批表现相对较差。

But this code is a good basis for a batch based search and replace utility, as long as you are willing to put up with the limitations and relatively poor performance of batch.

有提供更好的文本处理工具,虽然他们不能与Windows的标准。我最喜欢的是 GNU工具为Win32 包中的sed。公用事业都是免费的,不需要任何安装。

There are much better text processing tools available, though they are not standard with Windows. My favorite is sed within the GNU Utilities for Win32 package. The utilities are free, and do not require any installation.

下面是一个使用GNU工具为Windows SED解决方案

Here is a sed solution for Windows using GNU utilities

@echo off
setlocal
cd /d %~dp0
Set "OldString=\[HFloat(undefined),HFloat(undefined),HFloat(undefined)\],"
Set "NewString="
set file="test.mpl"
for %%F in (%file%) do set outFile="%%~nFCleaned%%~xF"
pause
sed -e"s/%OldString%/%NewString%/g" <%file% >%outfile%


更新2013年2月19日

sed的,如果你在有规则禁止从网上下载的可执行文件的安装现场工作可能不是一个选项。

sed may not be an option if you work at a site that has rules forbidding the installation of executables downloaded from the web.

JScript中具有良好的定期EX pression处理,这是所有现代的Windows平台,包括XP的标准。这是一个在Windows平台上执行搜索和替换操作一个不错的选择。

JScript has good regular expression handling, and it is standard on all modern Windows platforms, including XP. It is a good choice for performing search and replace operations on Windows platforms.

我写了一个混合的JScript /批量搜索和替换脚本(REPL.BAT),很容易从一个批处理脚本中调用。 code少量给出了很多强大的功能;不是那样强大的sed,但足以应付这个任务,以及许多别人多。这也是相当快的,比任何纯批次的解决方案快得多。它也没有任何固有的线长度的限制。

I have written a hybrid JScript/Batch search and replace script (REPL.BAT) that is easy to call from a batch script. A small amount of code gives a lot of powerful features; not as powerful as sed, but more than enough to handle this task, as well as many others. It is also quite fast, much faster than any pure batch solution. It also does not have any inherent line length limitations.

下面是一个使用我REPL.BAT工具来完成任务批处理脚本。

Here is a batch script that uses my REPL.BAT utility to accomplish the task.

@echo off
setlocal
cd /d %~dp0
Set "OldString=[HFloat(undefined),HFloat(undefined),HFloat(undefined)],"
Set "NewString="
set file="test.txt"
for %%F in (%file%) do set outFile="%%~nFCleaned%%~xF"
pause
call repl OldString NewString le <%file% >%outfile%

我用选项来指定文字搜索字符串,而不是一个普通的前pression,而电子选项通过搜索和名称替换,而不是使用命令行字符串通过环境变量字符串。

I use the L option to specify a literal search string instead of a regular expression, and the E option to pass the search and replace strings via environment variables by name, instead of using string literals on the command line.

下面是REPL.BAT实用脚本,上面code调用。完整的文档是在脚本中encluded。

Here is the REPL.BAT utility script that the above code calls. Full documentation is encluded within the script.

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

::************ Documentation ***********
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?
:::
:::  Performs a global 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.
:::
:::  Search  - By default this is a case sensitive JScript (ECMA) regular
:::            expression expressed as a string.
:::
:::            JScript 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.
:::            A $ literal can be escaped as $$. An empty replacement string
:::            must be represented as "".
:::
:::            Replace substitution pattern syntax is 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.
:::
:::            I - Makes the search case-insensitive.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in Replace are
:::                treated as $ literals.
:::
:::            E - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line. ^ anchors
:::                the beginning of a line and $ anchors the end of a line.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Ascii (Latin 1) character expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Escape sequences are supported even when the L option is 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.
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    findstr "^:::" "%~f0" | cscript //E:JScript //nologo "%~f0" "^:::" ""
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 1
  )
)
echo(%~3|findstr /i "[^SMILEX]" >nul && (
  call :err "Invalid option(s)"
  exit /b 1
)
cscript //E:JScript //nologo "%~f0" %*
exit /b 0

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

************* JScript portion **********/
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 srcVar=(options.indexOf("s")>=0);
if (srcVar) {
  options=options.replace(/s/g,"");
}
if (options.indexOf("e")>=0) {
  options=options.replace(/e/g,"");
  search=env(search);
  replace=env(replace);
}
if (options.indexOf("l")>=0) {
  options=options.replace(/l/g,"");
  search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
  replace=replace.replace(/\$/g,"$$$$");
}
if (options.indexOf("x")>=0) {
  options=options.replace(/x/g,"");
  replace=replace.replace(/\\\\/g,"\\B");
  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,"\\");
}
var search=new RegExp(search,options);

if (srcVar) {
  WScript.Stdout.Write(env(args.Item(3)).replace(search,replace));
} else {
  while (!WScript.StdIn.AtEndOfStream) {
    if (multi) {
      WScript.Stdout.Write(WScript.StdIn.ReadAll().replace(search,replace));
    } else {
      WScript.Stdout.WriteLine(WScript.StdIn.ReadLine().replace(search,replace));
    }
  }
}

这篇关于bat文件替换文本文件中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆