替换输出中的字符串

时间:2018-07-30 08:08:48

标签: batch-file

我有C:/test.txt文件,其内容如下。

05/13/2017 07:29:34 Value=           \\america.com\efpf_share\efpf\ipm_files
05/13/2017 07:29:41 Value=           \\america.com\efpf_share\efpf\ipm_files
05/17/2017 08:31:54 Value=           \\america.com\efpf_share\efpf\ipm_files
05/17/2017 08:32:03 Value=           \\america.com\efpf_share\efpf\ipm_files

我要提取“ epfp”或任何字符串,如果附加了测试(如epfptest),也将其转换成大写字母,则应拆分 EPFP-TEST 。为了进行提取,我运行以下代码并重定向 temp1.txt 文件

中的输出
findstr "Value=" C:\test.txt| findstr america > "C:\temp.txt" && for /l %l in (1,1,1) do @for /f "tokens=3* delims=." %a in ('findstr /n /r "^" "C:\temp.txt" ^| findstr /r "^%l:"') do @echo %b > c:\temp1.txt

现在的temp1.txt文件,其内容如下:

com\efpf_share\efpf\ipm_files

现在我终于从下面的代码中提取了efpf,它给出的输出如下:

for /f "tokens=3 delims=\" %a in (c:\temp1.txt) do @echo %a
epfp

我希望此输出或将其转换为 EPFP (在uppercare中),如果此输出未附加 test 字符串,则它应该只拆分为 EPFP-TEST

注意:最终输出可以是任何内容(在这种情况下为epfp),并且如果此输出包含附加的“ test”字符串,则我也希望将其转换为大写,然后应将其拆分为“ STRING -TEST

1 个答案:

答案 0 :(得分:0)

绝对不应使用批处理文件和纯Windows命令处理器命令来完成此测试文件修改任务。有更好的脚本语言可以完成此任务。

使用功能强大的文本编辑器(例如UltraEdit)或任何其他支持Perl正则表达式的文本编辑器来进行此文件内容修改也将更加有用。搜索(\\[^\\]+\\)(?=ipm_files)并用作替换字符串\U$1\E会将目录名ipm_files更改为大写,然后搜索(?<!\\|-)TEST(?=\\ipm_files)并用作替换字符串-TEST插入如果没有连字符,并且整个文件夹的名称不是TEST,则TEST左边的连字符。

但是,这是此任务的批处理批处理文件解决方案:

@echo off
if not exist "%~dp0Test.txt" goto :EOF
setlocal EnableExtensions DisableDelayedExpansion

set "Modified=0"
set "DataFile=%~dp0Test.txt"
set "TempFile=%TEMP%\%~n0.tmp"
del "%TempFile%" 2>nul

for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%DataFile%" 2^>nul') do (
    set "Line=%%I"
    call :ProcessLine
)

if %Modified% == 1 move /Y "%TempFile%" "%DataFile%"
del "%TempFile%" 2>nul

endlocal
goto :EOF

rem The subroutine ProcessLine removes first line number and colon inserted
rem by FINDSTR at beginning of each line to process correct also empty lines
rem in data file. The subroutine jumps to output of line in case of current
rem line is an empty line.

rem Next the line is split up into substrings using backslash as delimiter.
rem Of interest are only the fourth and fifth substrings. The fifth substring
rem should be ipm_files to identify the current line as a line to process.
rem A jump to writing the line into temporary file is done if this condition
rem is not true. Otherwise the fourth substring is assigned to a variable
rem because that string is the folder name to modify by this batch file.

rem Each ASCII character in the folder name is replaced by its upper case character.

rem If the entire new folder name is TEST, just do the replace and don't change
rem the folder name to -TEST. If the new folder name ends already with -TEST,
rem just do the replace. But if new folder name ends with only TEST, replace
rem just TEST by -TEST with hyphen.

rem A case-sensitive comparison of current and new folder name is done before
rem running the folder replace on line to determine if the replace is really
rem necessary at all. The modification information is saved in an environment
rem variable which is passed over local environment of subroutine to main code
rem above. This information is used finally to determine if the data file must
rem be replaced at all by the temporary file because of a modification is made
rem or the temporary file can be simply deleted as being equal with data file.

:ProcessLine
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if not defined Line goto WriteLine

for /F "tokens=4,5 delims=\" %%A in ("!Line!") do (
    if /I not "%%B" == "ipm_files" goto WriteLine
    set "CurFolderName=%%A"
)

set "NewFolderName=%CurFolderName%"
for %%C in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "NewFolderName=!NewFolderName:%%C=%%C!"

if "%NewFolderName%" == "TEST" goto DoReplace
if "%NewFolderName:~-5%" == "-TEST" goto DoReplace
if "%NewFolderName:~-4%" == "TEST" set "NewFolderName=%NewFolderName:~0,-4%-TEST"

:DoReplace
if "%CurFolderName%" == "%NewFolderName%" goto WriteLine
set "Modified=1"
set "Line=!Line:%CurFolderName%\ipm_files=%NewFolderName%\ipm_files!"

:WriteLine
echo(!Line!>>"%TempFile%"
endlocal & set "Modified=%Modified%"
goto :EOF

%~dp0Test.txt必须两次替换为具有相对或绝对路径的数据文件的真实文件名。

我对以下内容的回答中描述了顶部主要代码中第一个 FOR 循环的目的: How to read and print contents of text file line by line?

其他命令行由主代码和子例程之间的注释说明。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /?
  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • goto /?
  • if /?
  • move /?
  • rem /?
  • setlocal /?