Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Windows命令行替换线段分隔符或展开一条直线?_Windows_Batch File_Findstr - Fatal编程技术网

如何使用Windows命令行替换线段分隔符或展开一条直线?

如何使用Windows命令行替换线段分隔符或展开一条直线?,windows,batch-file,findstr,Windows,Batch File,Findstr,我们的系统将从Linux迁移到Windows机器,所以我准备了一个与现有脚本相当的批处理文件。我已经创建了批处理文件,但在处理下一行代码之前,我需要先打开该文件 例如。这里是一个单行程序,其中分隔符为“{”。 注意:分隔符可以是除元素分隔符(本例中为“~”)之外的任何字符或变量字符 我需要像这样展开它(相当于tr“{”“\n”

我们的系统将从Linux迁移到Windows机器,所以我准备了一个与现有脚本相当的批处理文件。我已经创建了批处理文件,但在处理下一行代码之前,我需要先打开该文件

例如。这里是一个单行程序,其中分隔符为“{”。 注意:分隔符可以是除元素分隔符(本例中为“~”)之外的任何字符或变量字符

我需要像这样展开它(相当于tr“{”“\n” 编辑: 打开包装后,如果第三个字段等于GS段(第2行)下的“1145837”,我需要搜索该字段的固定值,并将其替换为“1119283”(相当于sed'/^GS/s/1145837/1119283/)

下面是我的批处理文件。我需要将代码插入:WriteToLogFile子例程

@echo on

::This ensures the parameters are resolved prior to the internal variable
SetLocal EnableDelayedExpansion

rem Get current date and time as local time.
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| %SystemRoot%\System32\Find.exe "."') do set dt=%%a

rem Reformat the date and time strong to wanted format.
set "YYYY=%dt:~0,4%"
set "MM=%dt:~4,2%"
set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%"
set "Min=%dt:~10,2%"
set "Sec=%dt:~12,2%"
set "TimeStamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"

rem Define name of the list file containing current date and time in name.
set "ListFile=FLIST_%TimeStamp%.lst"

rem Change directory (and drive).
cd /D "C:\VP"

rem Create the list file which is good here as the list of files changes
rem while running this batch file and therefore it is better to work with
rem a list file instead of running a FOR directly for each file in the
rem directory. The list file is not included in this list as it either does
rem not exist at all or it has wrong file extension as only *.txt files are
rem listed by command DIR. The log file EDI.log has also wrong file extension.
dir *.txt /A:-D /B /O:D >"C:\VP\TEST\%ListFile%"

rem It might be useful to delete the log file from a previous run.
if exist EDI.log del EDI.log

rem Process each file in the list file.
cd /D "C:\VP\TEST"
for /F "delims=" %%F in ( %ListFile% ) do call :ProcessFile "%%F"
cd /D "C:\VP"

::rem Delete the list file as not needed anymore. It could be also kept.
::del %ListFile%

rem Exit batch file.
endlocal
goto :EOF


:ProcessFile
rem The parameter passed from first FOR is the file name in double quotes.
set "FileName=%~1"

rem Ignore the files CNtable.txt and Dupfile.txt in same directory.
rem Command goto :EOF just exits here from subroutine ProcessFile.
if "%FileName%"=="CNtable.txt" goto :EOF
if "%FileName%"=="Dupfile.txt" goto :EOF
if "%FileName%"=="VanPointAS2in.bat" goto :EOF
if "%FileName%"=="VP.bat" goto :EOF

rem Get 7th, 9th and 14th element from first line of current file.
cd /D "C:\VP"
for /f "usebackq tokens=7,9,14 delims=~*^" %%a in ( "%FileName%" ) do (
   set "ISAsender=%%a"
   set "ISAreceiver=%%b"
   set "ISActrlnum=%%c"
   goto WriteToLogFile
)

:WriteToLogFile
rem Remove all spaces as ISAsender and ISAreceiver have
rem usually spaces appended at end according to example
rem text. Then write file name and the 3 values to log file.
set "ISAsender=%ISAsender: =%"
set "ISAreceiver=%ISAreceiver: =%"
set "ISActrlnum=%ISActrlnum: =%"
echo %FileName%,%ISAsender%,%ISAreceiver%,%ISActrlnum%>>"C:\VP\TEST\EDI.log"

set "FLAG=N"
if "%ISAsender%"=="APPLESND" (
    if "%ISAreceiver%"=="MANGO" (
        set "FLAG=Y"
        set "VW=AP"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "APPLE"
        echo Moved %FileName% to directory APPLE.
    )
)

if "%ISAsender%"=="APPLESND" (
    if "%ISAreceiver%"=="MANGOES" (
        set "FLAG=Y"
        set "VW=AP"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "APPLE"
        echo Moved %FileName% to directory APPLE.
    )
)

if "%ISAsender%"=="SAMSUNGSND" (
    if "%ISAreceiver%"=="MANGO" (
        set "FLAG=Y"
        set "VW=SS"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "SAMSUNG"
        echo Moved %FileName% to directory SAMSUNG.
    )
)

rem Move to directory BYPASS if all else not satisfied.
if "%FLAG%"=="N" (
    move /Y "%FileName%" "BYPASS"
    echo Moved %FileName% to directory BYPASS
)

rem Exit the subroutine WriteToLogFile.
goto :EOF


:DupCheck
rem Check for ISA control number in file %VW%_table.txt.
%SystemRoot%\System32\Findstr.exe /X /M /C:%ISActrlnum% "C:\VP\TEST\%VW%_table.txt" >nul
if errorlevel 1 goto NewControl

rem This ISA control number is already present in file %VW%_table.txt.
echo Duplicate control %ISActrlnum% found in file %FileName%.
echo %ISActrlnum%,%FileName%>>"C:\VP\TEST\Dupfile.txt"
move /Y "%FileName%" "DUPLICATES"
echo Moved %FileName% to directory DUPLICATES.
rem Exit the subroutine DupCheck.
goto :EOF

:NewControl
echo %ISActrlnum%>>"C:\VP\TEST\%VW%_table.txt"

非常感谢您的帮助。

使用本机批处理命令操作文本文件相当棘手,而且速度相当慢。大多数任务都可以完成,但它需要相当多的高级批处理技术才能使解决方案更加健壮

您可能会对一个免费的unix Windows实用程序集合感到非常满意。然后您可以使用熟悉的工具操作文件内容

另一个很好的替代方法(我最喜欢的,因为我写了它)是使用一个混合JScript/批处理实用程序,它在stdin上执行regex搜索/替换操作,并将结果写入stdout。它是纯脚本,从XP开始将在任何Windows机器上运行。脚本中嵌入了完整的文档

我建议将行分隔符替换为
\r\n
,而不是
\n
,因为这是用于换行符的Windows标准

假设REPL.BAT位于当前目录中或路径中的某个位置,则以下内容将对您进行必要的更改:

set "file=fileName.txt"
type "fileName.txt" | repl "{" "\r\n" lx >"%file%.new"
move /y "%file%.new" "%file%" >nul

:GS_replace
<"%file%" call repl "^(GS~.*)1145837" "$11119283" >"%file%.new"
set "rtn=%errorlevel%"
move /y "%file%.new" "%file%" >nul
if %rtn% equ 0 goto GS_replace

感谢您的回复,我如何在repl变量中设置分隔符,因为文件可能包含其他段分隔符,如星号或任何字符?对于GS部分,如果第三个字段等于1145837,则只需将其替换为1119283,因为该字段为syntest。在这里,我需要搜索包含多个GS段和rep的完整文件如果第三个字段等于1145837Umm,请将变量
“%var%”
或参数
“%~1”
替换为常量
“{”
。我应该认为这是相当明显的。你在说什么第三个字段?-你的问题从来没有提到替换特定字段中的字符串。事实上,我看不出你发布的批处理脚本与你描述的问题有什么关系。你的unix代码示例是从一个文件中读取的,但哪里都没有:WriteLogFile从文件读取.EDIT-使用REPL.BAT版本5.0EDIT的新返回码功能简化了修改
GS~
行的循环-附加了一个解决方案,说明如何仅选择性地修改GS记录的第三个字段。很抱歉,我更新了我的问题。您的上一组代码完成了这项工作。很高兴您创建了ed REPL.bat的工作方式就像一个符咒。这对段分隔符部分正确吗,设置“var=%~1”,然后REPL“%var%”\r\n“lx>“%file%.new”替换段分隔符的变量值?
@echo on

::This ensures the parameters are resolved prior to the internal variable
SetLocal EnableDelayedExpansion

rem Get current date and time as local time.
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| %SystemRoot%\System32\Find.exe "."') do set dt=%%a

rem Reformat the date and time strong to wanted format.
set "YYYY=%dt:~0,4%"
set "MM=%dt:~4,2%"
set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%"
set "Min=%dt:~10,2%"
set "Sec=%dt:~12,2%"
set "TimeStamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"

rem Define name of the list file containing current date and time in name.
set "ListFile=FLIST_%TimeStamp%.lst"

rem Change directory (and drive).
cd /D "C:\VP"

rem Create the list file which is good here as the list of files changes
rem while running this batch file and therefore it is better to work with
rem a list file instead of running a FOR directly for each file in the
rem directory. The list file is not included in this list as it either does
rem not exist at all or it has wrong file extension as only *.txt files are
rem listed by command DIR. The log file EDI.log has also wrong file extension.
dir *.txt /A:-D /B /O:D >"C:\VP\TEST\%ListFile%"

rem It might be useful to delete the log file from a previous run.
if exist EDI.log del EDI.log

rem Process each file in the list file.
cd /D "C:\VP\TEST"
for /F "delims=" %%F in ( %ListFile% ) do call :ProcessFile "%%F"
cd /D "C:\VP"

::rem Delete the list file as not needed anymore. It could be also kept.
::del %ListFile%

rem Exit batch file.
endlocal
goto :EOF


:ProcessFile
rem The parameter passed from first FOR is the file name in double quotes.
set "FileName=%~1"

rem Ignore the files CNtable.txt and Dupfile.txt in same directory.
rem Command goto :EOF just exits here from subroutine ProcessFile.
if "%FileName%"=="CNtable.txt" goto :EOF
if "%FileName%"=="Dupfile.txt" goto :EOF
if "%FileName%"=="VanPointAS2in.bat" goto :EOF
if "%FileName%"=="VP.bat" goto :EOF

rem Get 7th, 9th and 14th element from first line of current file.
cd /D "C:\VP"
for /f "usebackq tokens=7,9,14 delims=~*^" %%a in ( "%FileName%" ) do (
   set "ISAsender=%%a"
   set "ISAreceiver=%%b"
   set "ISActrlnum=%%c"
   goto WriteToLogFile
)

:WriteToLogFile
rem Remove all spaces as ISAsender and ISAreceiver have
rem usually spaces appended at end according to example
rem text. Then write file name and the 3 values to log file.
set "ISAsender=%ISAsender: =%"
set "ISAreceiver=%ISAreceiver: =%"
set "ISActrlnum=%ISActrlnum: =%"
echo %FileName%,%ISAsender%,%ISAreceiver%,%ISActrlnum%>>"C:\VP\TEST\EDI.log"

set "FLAG=N"
if "%ISAsender%"=="APPLESND" (
    if "%ISAreceiver%"=="MANGO" (
        set "FLAG=Y"
        set "VW=AP"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "APPLE"
        echo Moved %FileName% to directory APPLE.
    )
)

if "%ISAsender%"=="APPLESND" (
    if "%ISAreceiver%"=="MANGOES" (
        set "FLAG=Y"
        set "VW=AP"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "APPLE"
        echo Moved %FileName% to directory APPLE.
    )
)

if "%ISAsender%"=="SAMSUNGSND" (
    if "%ISAreceiver%"=="MANGO" (
        set "FLAG=Y"
        set "VW=SS"
        call :DupCheck
        echo %errorlevel%>>"C:\VP\TEST\EDI.log"
        if errorlevel 1 move /Y "%FileName%" "SAMSUNG"
        echo Moved %FileName% to directory SAMSUNG.
    )
)

rem Move to directory BYPASS if all else not satisfied.
if "%FLAG%"=="N" (
    move /Y "%FileName%" "BYPASS"
    echo Moved %FileName% to directory BYPASS
)

rem Exit the subroutine WriteToLogFile.
goto :EOF


:DupCheck
rem Check for ISA control number in file %VW%_table.txt.
%SystemRoot%\System32\Findstr.exe /X /M /C:%ISActrlnum% "C:\VP\TEST\%VW%_table.txt" >nul
if errorlevel 1 goto NewControl

rem This ISA control number is already present in file %VW%_table.txt.
echo Duplicate control %ISActrlnum% found in file %FileName%.
echo %ISActrlnum%,%FileName%>>"C:\VP\TEST\Dupfile.txt"
move /Y "%FileName%" "DUPLICATES"
echo Moved %FileName% to directory DUPLICATES.
rem Exit the subroutine DupCheck.
goto :EOF

:NewControl
echo %ISActrlnum%>>"C:\VP\TEST\%VW%_table.txt"
set "file=fileName.txt"
type "fileName.txt" | repl "{" "\r\n" lx >"%file%.new"
move /y "%file%.new" "%file%" >nul

:GS_replace
<"%file%" call repl "^(GS~.*)1145837" "$11119283" >"%file%.new"
set "rtn=%errorlevel%"
move /y "%file%.new" "%file%" >nul
if %rtn% equ 0 goto GS_replace
:GS_replace
<"%file%" call repl "^(GS~(?:.*~)*)1145837(~|$)" "$11119283$2" >"%file%.new"
set "rtn=%errorlevel%"
move /y "%file%.new" "%file%" >nul
if %rtn% equ 0 goto GS_replace
:GS_replace
<"%file%" call repl "^(GS~(?:.*\D)*)1145837(\D|$)" "$11119283$2" >"%file%.new"
set "rtn=%errorlevel%"
move /y "%file%.new" "%file%" >nul
if %rtn% equ 0 goto GS_replace
type "%file%" | repl "^(GS~(.*?~){2})1145837(~|$)" "$11119283$2" >"%file%.new"
move /y "%file%.new" "%file%" >nul