【问题标题】:BAT file to replace string in two linesBAT文件以两行替换字符串
【发布时间】:2014-10-15 21:40:57
【问题描述】:

我正在 Windows 中编写一个脚本,一个 .BAT 文件来替换:

请注意,这里有一个 ENTER,我的意思是字符串分两行。现在看起来更复杂了:在 2 个双引号之后有 2 个空格,然后是 "ENTER"

""  
"2014

所以,类似:(双引号)(双引号)(空格)(空格)(换行)(双引号)2014

我遇到了这个问题。脚本如下所示:

@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=FILE_IN_CSV.csv
set OUTTEXTFILE=222.csv
set SEARCHTEXT=^"^"^"2014
set REPLACETEXT=^"^"^"4
set OUTPUTLINE=

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

    echo !modified! >> %OUTTEXTFILE%
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%

有什么想法吗?

谢谢!

编辑:添加源文本示例。看到每行末尾有 3 个(不是 2 个!)黑色空格。

"2014091810000076";"Question about folder sizes";"2014-09-18 12:10:20";"2014-09-25 17:33:15";"Resolt Sistemes";"jbgsfnam";"Sistemes::Altres";"STFD";"peticions";""   
"2014091910000109";"Error opening word files with office 2013";"2014-09-19 09:50:07";"2014-09-25 14:27:59";"Resolt TRO";"yerttom";"Qualitat::Altres";"STFD";"peticions";""   

我只需要删除每行开头的 20,而不是行中间的其他 20。

【问题讨论】:

  • 所以你有问题吗?需要详细说明吗?
  • 嗨,我只是添加一些源文本作为示例。谢谢!

标签: batch-file replace


【解决方案1】:
@ECHO OFF
SETLOCAL
(
 FOR /f "delims=" %%a IN (q6288377.txt) DO (
 SET line=%%a
 SETLOCAL ENABLEDELAYEDEXPANSION
 ECHO(^"!line:~3!
 endlocal
 )
)>newfile.txt
(
 FOR /f "delims=" %%a IN (q6288377.txt) DO (
 SET line=%%a
 SETLOCAL ENABLEDELAYEDEXPANSION
 IF "!line:~1,2!"=="20" (ECHO(^"!line:~3!) else (echo(%%a)
 endlocal
 )
)>newfile2.txt

GOTO :EOF

如果没有明确指出期望的结果,就很难解决“我的代码没有做我想要做的事情”这样的问题。

您的问题似乎是删除文本文件第 2 列和第 3 列中的“20”(我更改了名称以适合我的系统。)

上面的代码假定文件的每一行都以" 开头。第一部分任意删除第 2 列和第 3 列中的任何字符,创建newfile.txt。第二个只选择第 2 列和第 3 列中包含 20 的行并删除这些列,不理会其他行并创建 newfile2.txt

您已将要求从 ""SpaceSpaceNewline"2014 更改为 3 个终端空格,没有指示第一行是否为一个例外(它不会以 ""SpaceSpaceNewline 开头),因此上述内容可能不适用。不知道是否序列的存在是否重要——而且很可能,像sed 这样的实用程序更适合这项任务(谷歌是你的朋友)


[编辑扩展问题]

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
PUSHD "%sourcedir%"
FOR %%u IN (q6288377*.txt) DO (
(
 FOR /f "usebackqdelims=" %%a IN ("%%u") DO (
 SET line=%%a
 SETLOCAL ENABLEDELAYEDEXPANSION
 ECHO(^"!line:~3!
 endlocal
 )
)>%%~nu.xtx
)
popd

GOTO :EOF

您需要更改sourcedir 的设置以适应您的情况。生成的文件将是同名.xtx。不要尝试直接覆盖现有文件。

您还可以通过在 %%~nu.xtx 前加上目录名称来在不同的目录中创建新文件,例如“c:\some random\directory\%%~nu.xtx” - 如果目录或文件名包含分隔符(如空格)。 ~nu 表示“%%u 的名称 - 请参阅提示中的 for /? 以获取更多信息。

解决整个问题总是比零敲碎打更容易。完整的描述可能会影响所使用的方法。

【讨论】:

  • 这段代码运行良好,谢谢!让我问你最后一个问题:是否可以修改此脚本以将其应用于文件夹中的所有 CSV 文件?
【解决方案2】:

你的方法永远行不通。

  1. 命令for 总是逐行处理文本。因此,不可能将 2 行作为字符串放入环境变量中并修改此字符串。

  2. 段落符号 (代码值 B6 十六进制)只是查看显示行尾的文本文件时的占位符。 CSV 文件包含回车 (0D) 和换行 (0A),命令 for 始终将其解释为独立于您指定的分隔符。

最好使用 UltraEdit 或 Notepad++ 或 Sublime Text 等文本编辑器在文件中进行替换。甚至不需要在这些编辑器中运行正则表达式替换。但是使用 Perl 正则表达式 ""\s+"2014 作为搜索字符串和替换字符串 """4 会导致您想要的修改。

还有为替换文件中的字符串而编写的控制台应用程序。看看How can you find and replace text in a file using the Windows command-line environment?

在文件中搜索"" \r\n"2014 并将其替换为"""4 仅使用标准命令仍然可以使用下面的代码。

@echo off
setlocal EnableDelayedExpansion
set "INTEXTFILE=FILE_IN_CSV.csv"

if not exist "%INTEXTFILE%" goto EndBatch

set "OUTTEXTFILE=%TEMP%\csv_replace.tmp"
if exist "%OUTTEXTFILE%" del "%OUTTEXTFILE%"

set "FirstLine="
set "EndFirstLine=""  "
set "BeginSecondLine="2014"

for /f "usebackq delims=" %%A in ("%INTEXTFILE%") do (
    set "Line=%%A"
    if not "!FirstLine!"=="" (
        if "!Line:~0,5!"=="!BeginSecondLine!" (
            set "FirstLine=!FirstLine!"!Line:~4!"
            echo !FirstLine!>>"%OUTTEXTFILE%"
            set "Line="
        ) else (
            echo !FirstLine!  >>"%OUTTEXTFILE%"
        )
        set "FirstLine="
    )
    if not "!Line!"=="" (
        if "!Line:~-4!"=="!EndFirstLine!" (
            set "FirstLine=!Line:~0,-2!"
        ) else (
            echo !Line!>>"%OUTTEXTFILE%"
        )
    )
)

if exist "%OUTTEXTFILE%" (
    copy "%OUTTEXTFILE%" "%INTEXTFILE%" >nul
    del "%OUTTEXTFILE%"
)

:EndBatch
endlocal

这个批处理文件也会删除空行。这是无法避免的,因为命令 for 在解析文件时会忽略空行。

【讨论】:

  • 这个脚本不适合我。我用一个代码示例编辑了最初的帖子。谢谢!
  • 所以你只想修剪尾随空格并从所有行中删除第二个和第三个字符(世纪)。这与最初描述的完全不同。我认为,CSV 文件中的字段值中有换行符,因此有必要在某些条件下将两行连接到一行。所以我为真正需要的东西写了一个完全错误的代码。输入和输出示例始终是描述此类任务的最佳方式。
  • 是的,你说得对,对不起。我忘记发布源文本的示例。
猜你喜欢
  • 2011-08-14
  • 2017-06-23
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多